<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>R-bloggers</title>
	<atom:link href="https://www.r-bloggers.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.r-bloggers.com</link>
	<description>R news and tutorials contributed by hundreds of R bloggers</description>
	<lastBuildDate>Tue, 04 Aug 2026 13:57:51 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.5.18</generator>

<image>
	<url>https://i0.wp.com/www.r-bloggers.com/wp-content/uploads/2016/08/cropped-R_single_01-200.png?fit=32%2C32&#038;ssl=1</url>
	<title>R-bloggers</title>
	<link>https://www.r-bloggers.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">11524731</site>	<item>
		<title>R GUI Comparison Update</title>
		<link>https://www.r-bloggers.com/2026/08/r-gui-comparison-update/</link>
		
		<dc:creator><![CDATA[Bob Muenchen]]></dc:creator>
		<pubDate>Tue, 04 Aug 2026 13:57:51 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://r4stats.com/?p=5580</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> Graphical user interfaces for the R language are easy to use and getting more powerful all the time. Here is my updated comparison of jamovi, JASP, BlueSky Statistics (free &#038; Pro), Rattle, RKWard, R-Instat, R AnalyticFlow, and R Commander. With so many detailed reviews of Graphical User Interfaces (GUIs) for R ...</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/r-gui-comparison-update/">R GUI Comparison Update</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://r4stats.com/2026/08/04/r-gui-comparison-update/"> R | r4stats.com</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<p class="wp-block-paragraph">Graphical user interfaces for the R language are easy to use and getting more powerful all the time. Here is my updated comparison of jamovi, JASP, BlueSky Statistics (free &#038; Pro), Rattle, RKWard, R-Instat, R AnalyticFlow, and R Commander.</p>



<p class="wp-block-paragraph">With so many <a href="https://r4stats.com/articles/software-reviews" rel="nofollow" target="_blank">detailed reviews</a> of Graphical User Interfaces (GUIs) for R available, which should you choose? It’s not too difficult to rate them based on the number of features they offer, so I’ll start there. Then, I’ll follow with a brief overview of each.</p>



<p class="wp-block-paragraph">I’m basing the counts on the number of dialog boxes in each category of the following categories:</p>



<ul class="wp-block-list">
<li>Ease of Use</li>



<li>General Usability</li>



<li>Graphics</li>



<li>Analytics</li>



<li>Reproducibility</li>
</ul>



<p class="wp-block-paragraph">This <span style="margin: 0px; padding: 0px;">data is trickier to collect than you might think. Some software has fewer menu choices, depending instead on more detailed dialog boxes. Studying every menu and dialog box is very time-consuming, but that is what I’ve tried to do to keep this comparison <a href="https://r4stats.com/articles/software-reviews/why-you-should-trust-my-reviews/" rel="nofollow" target="_blank">trustworthy</a>. </span></p>



<p class="wp-block-paragraph">Perhaps the biggest flaw in this methodology is that every feature adds only one point to each GUI’s total score. I encourage you to <a href="https://1drv.ms/f/s!Aj_lpIYJgUBsk_1ydZxopRdgnskQAg?e=s4ccfW" rel="nofollow" title="" target="_blank">download</a> the full dataset and consider which features are most important to you. If you decide to make your own graphs with a different weighting system, I’d love to hear from you in the comments below. Thomas Langkamp did an excellent comparison focused on teaching statistics. You can read it <a href="https://www.researchgate.net/publication/392546873_The_Best_App_for_Teaching_Statistics_How_to_Switch_-_Software_designed_for_teachers_students_to_improve_upon_RStudio_SPSS_and_siblings" title="" rel="nofollow" target="_blank">here</a>.</p>



<h2 class="wp-block-heading">Ease of Use</h2>



<p class="wp-block-paragraph">For ease of use, I’ve defined it primarily by how well each GUI meets its primary goal: avoiding code. They get one point for each of the following abilities, which include being able to install, start, and use the GUI to its maximum effect, including publication-quality output, without knowing anything about the R language itself. Figure 1 shows the result. R Commander is abbreviated Rcmdr, and R AnalyticFlow is abbreviated RAF. The commercial BlueSky Pro comes out on top by a slim margin, followed closely by JASP and RKWard. None of the GUIs achieved the highest possible score of 15, so there is room for improvement.</p>



<p class="wp-block-paragraph">The ease of use features are:</p>



<ul class="wp-block-list">
<li>Installs without the use of R</li>



<li>Starts without the use of R</li>



<li>Remembers recent files</li>



<li>Hides R code by default</li>



<li>Uses its full capability without needing R code</li>



<li>Data editor included</li>



<li>Pub-quality tables w/out R code steps</li>



<li>Simple menus that grow as needed</li>



<li>Table of Contents to ease navigation</li>



<li>Variable labels ease identification in the output</li>



<li>Easy to move blocks of output</li>



<li>Ease reading columns by freezing headers of long tables</li>



<li>Accepts data pasted from the clipboard</li>



<li>Easy to move header row of pasted data into the variable name field</li>



<li>Includes AI interface to ease interpretation of output</li>
</ul>



<figure class="wp-block-image size-full"><a href="https://i2.wp.com/r4stats.com/wp-content/uploads/2026/08/Ease_of_Use.png?ssl=1" rel="nofollow" target="_blank"><img loading="lazy" fetchpriority="high" decoding="async" data-attachment-id="5556" data-permalink="https://r4stats.com/articles/software-reviews/r-gui-comparison/ease_of_use-5/" data-orig-file="https://i2.wp.com/r4stats.com/wp-content/uploads/2026/08/Ease_of_Use.png?w=450&#038;ssl=1" data-orig-size="600,500" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","alt":""}" data-image-title="Ease_of_Use" data-image-description="" data-image-caption="" data-large-file="https://i2.wp.com/r4stats.com/wp-content/uploads/2026/08/Ease_of_Use.png?w=450&#038;ssl=1" src="https://i2.wp.com/r4stats.com/wp-content/uploads/2026/08/Ease_of_Use.png?w=450&#038;ssl=1" alt="" class="wp-image-5556" srcset_temp="https://i2.wp.com/r4stats.com/wp-content/uploads/2026/08/Ease_of_Use.png?w=450&#038;ssl=1 600w, https://r4stats.com/wp-content/uploads/2026/08/Ease_of_Use-300x250.png 300w" sizes="(max-width: 600px) 100vw, 600px" data-recalc-dims="1" /></a><figcaption class="wp-element-caption">Figure 1. The number of ease-of-use features offered by each R GUI.</figcaption></figure>



<h2 class="wp-block-heading">General Usability</h2>



<p class="wp-block-paragraph">This category is dominated by data-wrangling capabilities, which data scientists and statisticians spend most of their time on. It also includes various types of data input and output. We see in Figure 2 that both BlueSky versions and R-Instat come out on top, not just due to their excellent selection of data-wrangling features but also for their use of the rio package for importing and exporting files. The <a href="https://cran.r-project.org/web/packages/rio/vignettes/rio.html" rel="nofollow" target="_blank">rio</a> package combines the import/export capabilities of many other packages, and it is easy to use. I expect the other GUIs will eventually adopt it, raising their scores by around 20 points. </p>



<p class="wp-block-paragraph">The general usability features are:</p>



<ul class="wp-block-list">
<li>Operating systems (how many)</li>



<li>Import data file types (how many)</li>



<li>Import from databases (how many)</li>



<li>Export data file types (how many)</li>



<li>Languages displayable in UI (how many, besides English)</li>



<li>Easy to repeat any step by groups (split-file)</li>



<li>Multiple data files open at once</li>



<li>Multiple output windows</li>



<li>Multiple code windows</li>



<li>Variable metadata view</li>



<li>Variable types (how many)</li>



<li>Variable search/filter in dialogs</li>



<li>Variable sort by name</li>



<li>Variable sort by type</li>



<li>Variable move manually</li>



<li>Model Builder (how many effect types)</li>



<li>Magnify GUI for teaching</li>



<li>R code editor</li>



<li>Comment/uncomment blocks of code</li>



<li>Package management (comes with R and all packages)</li>



<li>Output: word processing features</li>



<li>Output: R Markdown</li>



<li>Output: LaTeX</li>



<li>Data wrangling (how many)</li>



<li>Transform across many variables at once (e.g., row mean)</li>



<li>Transform down many variables at once (e.g., log, sqrt)</li>



<li>Assign factor labels across many variables at once</li>



<li>Project saves/loads data, dialogs, and notes in one file</li>
</ul>



<figure class="wp-block-image size-full"><a href="https://i0.wp.com/r4stats.com/wp-content/uploads/2026/08/General_Usability.png?ssl=1" rel="nofollow" target="_blank"><img loading="lazy" decoding="async" data-attachment-id="5559" data-permalink="https://r4stats.com/articles/software-reviews/r-gui-comparison/general_usability-6/" data-orig-file="https://i0.wp.com/r4stats.com/wp-content/uploads/2026/08/General_Usability.png?w=450&#038;ssl=1" data-orig-size="600,500" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","alt":""}" data-image-title="General_Usability" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/r4stats.com/wp-content/uploads/2026/08/General_Usability.png?w=450&#038;ssl=1" src="https://i0.wp.com/r4stats.com/wp-content/uploads/2026/08/General_Usability.png?w=450&#038;ssl=1" alt="" class="wp-image-5559" srcset_temp="https://i0.wp.com/r4stats.com/wp-content/uploads/2026/08/General_Usability.png?w=450&#038;ssl=1 600w, https://r4stats.com/wp-content/uploads/2026/08/General_Usability-300x250.png 300w" sizes="(max-width: 600px) 100vw, 600px" data-recalc-dims="1" /></a><figcaption class="wp-element-caption">Figure 2. The number of general usability features in each R GUI.</figcaption></figure>



<h2 class="wp-block-heading">Graphics</h2>



<p class="wp-block-paragraph">This category consists mainly of the number of plot types each software offers. However, the other items can be very important to completing your work. They should add more than one point to the graphics score, but I scored them one point since some will view them as very important while others might not need them at all. Be sure to see the full reviews or download the Excel file if those features are important to you. Figure 3 shows the total graphics score for each GUI. jamovi has a solid lead in this category. R-Instat’s ability to layer any geometric object, or “geom,” on top of another could substantially increase its count, but I don’t include that since it requires knowledge of R code.</p>



<p class="wp-block-paragraph">When studying all the graphs in this article, it’s important to consider the difference between the relative and absolute performance. For example, relatively speaking, R Commander is not doing well here, but it does offer over 25 types of plots! That might be fine for your needs.</p>



<p class="wp-block-paragraph">The graphics features are:</p>



<ul class="wp-block-list">
<li>Types of graphs (how many)</li>



<li>Small multiples (i.e., facets)</li>



<li>Large multiples (i.e., by group / split-file)</li>



<li>Export graphics formats (how many)</li>



<li>Interactive Plot Builder</li>



<li>Interactive Plot Editor (e.g., add annotations, arrows, etc.)</li>



<li>Able to combine any graphs into a single image</li>
</ul>



<p class="wp-block-paragraph"><a href="https://r4stats.com/articles/software-reviews/r-gui-comparison/" title="" rel="nofollow" target="_blank">Continued</a>…</p>



<p class="wp-block-paragraph"></p>The post <a href="https://r4stats.com/2026/08/04/r-gui-comparison-update/" rel="nofollow" target="_blank">R GUI Comparison Update</a> first appeared on <a href="https://r4stats.com/" rel="nofollow" target="_blank">r4stats.com</a>.
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://r4stats.com/2026/08/04/r-gui-comparison-update/"> R | r4stats.com</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/r-gui-comparison-update/">R GUI Comparison Update</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402963</post-id>	</item>
		<item>
		<title>Centering a map projection on the mapped region</title>
		<link>https://www.r-bloggers.com/2026/08/centering-a-map-projection-on-the-mapped-region/</link>
		
		<dc:creator><![CDATA[A.M. Barbosa]]></dc:creator>
		<pubDate>Tue, 04 Aug 2026 13:11:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">http://modtools.wordpress.com/?p=3510</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> The PROJ format for defining Coordinate Reference Systems (CRS) is becoming deprecated, as PROJ strings cannot accurately store modern datum transformations, coordinate epoch information, or complex axis order rules. However, that format is much easier and more practical for humans … Continue reading →</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/centering-a-map-projection-on-the-mapped-region/">Centering a map projection on the mapped region</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://modtools.wordpress.com/2026/08/04/centering-a-map-projection-on-the-mapped-region/"> modTools</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>

<p class="wp-block-paragraph">The PROJ format for defining Coordinate Reference Systems (CRS) is becoming deprecated, as PROJ strings cannot accurately store modern datum transformations, coordinate epoch information, or complex axis order rules. However, that format is much easier and more practical for humans to type and read, and it is still often used as a legacy convenience. I, for one, use it often for centering a map projection on the mapped region, thus avoiding the distortion that occurs away from the projection center. For example, imagine I want to map New Zealand in a Lambert Azimuthal Equal-Area projection in R:</p>


<div class="wp-block-code">
	<div class="cm-editor">
		<div class="cm-scroller">
			
<pre>
library(terra)library(geodata)nz &lt;- gadm(country = &quot;New Zealand&quot;, level = 0, path = tempdir())nz_prj &lt;- project(nz, &quot;+proj=laea&quot;)plot(nz_prj)</pre>
		</div>
	</div>
</div>


<figure class="wp-block-image size-large is-resized"><a href="https://i1.wp.com/modtools.wordpress.com/wp-content/uploads/2026/08/image.png?ssl=1" rel="nofollow" target="_blank"><img loading="lazy" data-attachment-id="3515" data-permalink="https://modtools.wordpress.com/2026/08/04/centering-a-map-projection-on-the-mapped-region/image-28/" data-orig-file="https://modtools.wordpress.com/wp-content/uploads/2026/08/image.png" data-orig-size="1098,418" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","alt":""}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://modtools.wordpress.com/wp-content/uploads/2026/08/image.png?w=584" src="https://i1.wp.com/modtools.wordpress.com/wp-content/uploads/2026/08/image.png?w=450&#038;ssl=1" alt="" class="wp-image-3515" style="aspect-ratio:2.5363167486418208;width:465px;height:auto" srcset_temp="https://i1.wp.com/modtools.wordpress.com/wp-content/uploads/2026/08/image.png?w=450&#038;ssl=1 1024w, https://modtools.wordpress.com/wp-content/uploads/2026/08/image.png?w=150 150w, https://modtools.wordpress.com/wp-content/uploads/2026/08/image.png?w=300 300w, https://modtools.wordpress.com/wp-content/uploads/2026/08/image.png?w=768 768w, https://modtools.wordpress.com/wp-content/uploads/2026/08/image.png 1098w" sizes="(max-width: 1024px) 100vw, 1024px" data-recalc-dims="1" /></a></figure>



<p class="wp-block-paragraph">The map is heavily distorted, because it is far away from the center of the projection, which is 0,0 by default. With the PROJ format, we can easily set the center wherever we want, e.g.:</p>


<div class="wp-block-code">
	<div class="cm-editor">
		<div class="cm-scroller">
			
<pre>
nz_centr &lt;- crds(centroids(aggregate(nz)))nz_centr  # 172.6104 -41.82592nz_prj &lt;- project(nz, &quot;+proj=laea +lat_0=-41.8 +lon_0=172.6&quot;)# (this can be further automated to avoid the hard-coding,# but I keep it like this here for simplicity) plot(nz_prj)</pre>
		</div>
	</div>
</div>


<figure class="wp-block-image size-large is-resized"><a href="https://i0.wp.com/modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png?ssl=1" rel="nofollow" target="_blank"><img loading="lazy" data-attachment-id="3518" data-permalink="https://modtools.wordpress.com/2026/08/04/centering-a-map-projection-on-the-mapped-region/image-29/" data-orig-file="https://modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png" data-orig-size="796,1373" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","alt":""}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=584" src="https://i0.wp.com/modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=450&#038;ssl=1" alt="" class="wp-image-3518" style="aspect-ratio:0.58568329013069;width:179px;height:auto" srcset_temp="https://i0.wp.com/modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=450&#038;ssl=1 594w, https://modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=87 87w, https://modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=174 174w, https://modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=768 768w, https://modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png 796w" sizes="(max-width: 594px) 100vw, 594px" data-recalc-dims="1" /></a></figure>



<p class="wp-block-paragraph">Much better! We now have an equal-area map of New Zealand without visibly distorting the shape, and without having to look for specific equal-area CRSs normally used over there (and again every time we need to map another region of the world). This works as long as we use the WGS84 ellipsoid rather than a local datum, as those are currently not supported when using PROJ. So, I’m still using this regularly, and apprehensive about PROJ being deprecated… If anyone knows of a non-PROJ way of easily defining user-centered projections like this, please let me know!</p>



<p class="wp-block-paragraph"></p>

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://modtools.wordpress.com/2026/08/04/centering-a-map-projection-on-the-mapped-region/"> modTools</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/centering-a-map-projection-on-the-mapped-region/">Centering a map projection on the mapped region</a>]]></content:encoded>
					
		
		<enclosure url="https://2.gravatar.com/avatar/e1a349777384e70d2eb7ee3f26788864b1c880ec271cfc1cb8f9d8cc3000cd11?s=96&#038;d=retro&#038;r=G" length="0" type="" />
<enclosure url="https://modtools.wordpress.com/wp-content/uploads/2026/08/image.png?w=1024" length="0" type="" />
<enclosure url="https://modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=594" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402961</post-id>	</item>
		<item>
		<title>JAGS 5.0.0 is released</title>
		<link>https://www.r-bloggers.com/2026/08/jags-5-0-0-is-released/</link>
		
		<dc:creator><![CDATA[Martyn]]></dc:creator>
		<pubDate>Sun, 02 Aug 2026 16:44:02 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">http://martynplummer.wordpress.com/?p=2061</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> After an extended beta period, JAGS 5.0.0 is now available. The release is more of a process than a single event, but we have started by uploading the source tarball and the Windows installer to SourceForge. The macOS installer will … Continue reading →</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/jags-5-0-0-is-released/">JAGS 5.0.0 is released</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://martynplummer.wordpress.com/2026/08/02/jags-5-0-0-is-released/"> R – JAGS News</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>

<figure class="wp-block-image size-large"><img loading="lazy" data-attachment-id="2066" data-permalink="https://martynplummer.wordpress.com/img_0134/" data-orig-file="https://martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg" data-orig-size="2000,1500" data-comments-opened="1" data-image-meta="{"aperture":"1.64","credit":"","camera":"iPhone 16e","caption":"","created_timestamp":"1784045517","copyright":"","focal_length":"4.2","iso":"20","shutter_speed":"0.00019398642095053","title":"","orientation":"1","alt":""}" data-image-title="img_0134" data-image-description="" data-image-caption="" data-large-file="https://martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg?w=584" src="https://i0.wp.com/martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg?w=450&#038;ssl=1" alt="" class="wp-image-2066" title="img_0134" srcset_temp="https://i0.wp.com/martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg?w=450&#038;ssl=1 1024w, https://martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg?w=150 150w, https://martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg?w=300 300w, https://martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg?w=768 768w, https://martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg?w=1440 1440w, https://martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg 2000w" sizes="(max-width: 1024px) 100vw, 1024px" data-recalc-dims="1" /><figcaption class="wp-element-caption">View over Loch Muick, Balmoral Estate, Scotland</figcaption></figure>



<p class="wp-block-paragraph">After an extended beta period, JAGS 5.0.0 is now available. The release is more of a process than a single event, but we have started by uploading the <a href="https://sourceforge.net/projects/mcmc-jags/files/JAGS/5.x/Source/" rel="nofollow" target="_blank">source tarball</a> and the <a href="https://sourceforge.net/projects/mcmc-jags/files/JAGS/5.x/Windows/Rtools45/" rel="nofollow" target="_blank">Windows installer</a> to SourceForge. The macOS installer will be along hopefully next week.</p>



<p class="wp-block-paragraph">Thanks to Jeroen Ooms, Windows binary installers are available from the <a href="https://github.com/r-windows/JAGS/releases" rel="nofollow" target="_blank">r-windows project on GitHub</a>. This includes binaries for aarch64/Arm64.</p>



<h2 class="wp-block-heading">Changes since the beta release</h2>



<ul class="wp-block-list">
<li>Better multi-core support on macOS (More on this in a future post).</li>



<li>Fixed a delayed rejection bug in the <code>MNormal</code> sampler.</li>



<li>Added a new elliptical slice sampler contributed by Marcel Jonker. </li>



<li>The <code>dic.samples</code> function could throw a logic error (<a href="https://sourceforge.net/p/mcmc-jags/bugs/66/" rel="nofollow" target="_blank">See ticket #66)</a>. I am unable to reproduce this but JAGS 5.0.0 includes a workaround that should avoid triggering this bug.</li>



<li>Fixed a reproducibility bug in <code>BaseRNGFactory.</code></li>
</ul>



<p class="wp-block-paragraph">I would not normally add a new sampler at this late stage, but the elliptical slice sampler was ready to go and performs surprisingly well for a non-adaptive sampler. If you experience any trouble with this new sampler then you can turn it of with</p>


<div class="wp-block-code">
	<div class="cm-editor">
		<div class="cm-scroller">
			
<pre>
set.factory(&quot;bugs::EllipticalSlice&quot;, type=&quot;sampler&quot;, state=FALSE)</pre>
		</div>
	</div>
</div>


<p class="wp-block-paragraph">JAGS will then fall back on the adaptive random walk Metropolis-Hastings sampler <code>MNormal</code>.</p>



<h2 class="wp-block-heading">The rjags package and CRAN migration</h2>



<p class="wp-block-paragraph">The current rjags package on CRAN (<a href="https://cran.r-project.org/package=rjags" rel="nofollow" target="_blank">version 4-17</a>) will not work with JAGS 5.0.0. You need version 5-x but for the time being this will only be available from SourceForge.</p>



<ul class="wp-block-list">
<li><a href="https://sourceforge.net/projects/mcmc-jags/files/rjags/5/Source/" rel="nofollow" target="_blank">Source tarball</a></li>



<li><a href="https://sourceforge.net/projects/mcmc-jags/files/rjags/5/Windows/" rel="nofollow" target="_blank">Windows binary</a> (x86_64)</li>



<li><a href="https://sourceforge.net/projects/mcmc-jags/files/rjags/5/macOS/" rel="nofollow" target="_blank">macOS binary</a></li>
</ul>



<p class="wp-block-paragraph">The reason for not uploading the rjags package to CRAN is that it currently breaks a lot of reverse dependencies. I have been quite proactive in contacting the maintainers of these package and providing patches, but we still need to give them more time.</p>



<p class="wp-block-paragraph">We are monitoring the reverse dependency situation and will be liaising with the CRAN maintainers.</p>



<h2 class="wp-block-heading">Preview of upcoming posts</h2>



<p class="wp-block-paragraph">In order to help users and developers with the transition to JAGS version 5, a series of “What’s new in JAGS 5.0.0” blog posts are planned covering the following topics.</p>



<ul class="wp-block-list">
<li><strong>Initial values</strong></li>



<li><strong>Reproducibility</strong></li>



<li><strong>Multicore support</strong></li>



<li><strong>ABI compatibility</strong></li>



<li><strong>New diagnostics</strong></li>
</ul>



<p class="wp-block-paragraph">These will include guidance for package maintainers to make the transition to JAGS 5.0.0.</p>



<p class="wp-block-paragraph"></p>

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://martynplummer.wordpress.com/2026/08/02/jags-5-0-0-is-released/"> R – JAGS News</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/jags-5-0-0-is-released/">JAGS 5.0.0 is released</a>]]></content:encoded>
					
		
		<enclosure url="https://martynplummer.wordpress.com/wp-content/uploads/2026/05/img_0083.jpg" length="0" type="" />
<enclosure url="https://0.gravatar.com/avatar/fdc509bd31ae635d89cccbdc64ef09464ea1c20d7858c4089a07ea3bea91b8e3?s=96&#038;d=identicon&#038;r=G" length="0" type="" />
<enclosure url="https://martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg?w=1024" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402933</post-id>	</item>
		<item>
		<title>How Do I Build a Model? A Starting Guide for New Modellers</title>
		<link>https://www.r-bloggers.com/2026/08/how-do-i-build-a-model-a-starting-guide-for-new-modellers/</link>
		
		<dc:creator><![CDATA[Seascapemodels]]></dc:creator>
		<pubDate>Sun, 02 Aug 2026 14:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://www.seascapemodels.org/posts/2026-08-03-how-do-i-build-a-model/</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>I’ve put together a short guide: How Do I Build a Model? A starting guide for new modellers. It’s free, online, and aimed squarely at the graduate student who has a research question and is staring at a blank script wondering where to even begin...</p></div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/how-do-i-build-a-model-a-starting-guide-for-new-modellers/">How Do I Build a Model? A Starting Guide for New Modellers</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://www.seascapemodels.org/posts/2026-08-03-how-do-i-build-a-model/"> Seascapemodels</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
 





<p>I’ve put together a short guide: <em>How Do I Build a Model? A starting guide for new modellers</em>. It’s free, online, and aimed squarely at the graduate student who has a research question and is staring at a blank script wondering where to even begin.</p>
<p>You can read it online at <a href="https://www.seascapemodels.org/building-ecological-models/" rel="nofollow" target="_blank">How Do I Build a Model?</a>, or <a href="https://github.com/cbrown5/building-ecological-models/blob/main/docs/How-Do-I-Build-a-Model-.pdf" rel="nofollow" target="_blank">download a pdf</a>.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i1.wp.com/www.seascapemodels.org/posts/2026-08-03-how-do-i-build-a-model/flowchart-loop.png?w=578&#038;ssl=1" class="img-fluid figure-img" data-recalc-dims="1"></p>
<figcaption>First sketch, one of the steps on the way to buliding a working model</figcaption>
</figure>
</div>
<p>I’ve never settled into one corner of ecological modelling. I’m not the Bayesian guy, or the foodweb model guy, or the machine learning guy, though I’ve dabbled in all three. That haphazard career has given me a broad view across a lot of different modelling traditions, and I keep noticing the same meta-principles showing up regardless of the discipline. This guide is my attempt to write those down.</p>
<p>It’s not a textbook on any particular method. Once you know what type of model you’re building, go read a book by a discipline expert (I’ve listed some favourites in the final chapter). This guide is for the step before that: turning a question into a model in the first place.</p>
<section id="whats-in-it" class="level2">
<h2 class="anchored" data-anchor-id="whats-in-it">What’s in it</h2>
<ol type="1">
<li><strong>Start with the question.</strong> How you actually grow into a research question, through reading, writing, and talking it through with people whose work you admire (and some whose work you don’t).</li>
<li><strong>From a question to a type of model.</strong> Once you know your question, how to read papers differently, paying attention to the <em>how</em> and the <em>why</em>.</li>
<li><strong>Terminology: variables, parameters, and the rest.</strong> A clean-up of vocabulary that gets used loosely and causes confusion.</li>
<li><strong>Know why you’re building a model.</strong> Causal inference, prediction, or something else. Knowing your purpose is what narrows down the type of model you need.</li>
<li><strong>Sketching your model.</strong> Why you should start at a whiteboard with boxes and arrows before you touch an equation, and how to read those arrows as equations later.</li>
<li><strong>The different types of uncertainty.</strong> Why “how uncertain am I?” is really several different questions, and why that distinction matters for what you do next.</li>
<li><strong>Writing your model’s equations.</strong> Turning the diagram into notation, with a nod to Edwards &#038; Auger-Méthé’s guidance for ecologists, which I’d recommend reading in full regardless.</li>
<li><strong>Understand your constraints.</strong> Computational, data, and time constraints, and how they shape what model you can realistically build.</li>
<li><strong>The modelling workflow.</strong> Feedback loops of writing code, debugging, running, plotting, interpreting.</li>
<li><strong>Tools and software.</strong> The endless R-versus-Python debate, and why your own familiarity with a tool is a constraint.</li>
<li><strong>Tips for finding novel insights.</strong> Some of my favourite tricks, including hunting for analogues in other fields and pushing them to their extreme.</li>
</ol>
<p>There’s also a short further-reading list at the end, covering the books I’d point you to once you’ve picked your modelling approach.</p>
</section>
<section id="how-it-came-together" class="level2">
<h2 class="anchored" data-anchor-id="how-it-came-together">How it came together</h2>
<p>I dictated the original version on a long drive, Claude Code cleaned up the transcript into a first written draft and set up the Quarto book site, and I edited it from there.</p>


</section>

 
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://www.seascapemodels.org/posts/2026-08-03-how-do-i-build-a-model/"> Seascapemodels</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/how-do-i-build-a-model-a-starting-guide-for-new-modellers/">How Do I Build a Model? A Starting Guide for New Modellers</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402938</post-id>	</item>
		<item>
		<title>Analyzing Financial Trends: Kalman Filtering for Gold vs Bitcoin</title>
		<link>https://www.r-bloggers.com/2026/08/analyzing-financial-trends-kalman-filtering-for-gold-vs-bitcoin/</link>
		
		<dc:creator><![CDATA[Selcuk Disci]]></dc:creator>
		<pubDate>Sun, 02 Aug 2026 12:45:19 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">http://datageeek.com/?p=12417</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> In their paper “A Synchronized Multi‑IMU Wearable System for Tracking of Joint‑Angles in Sports Motion Analysis” (arXiv:2607.26027v1), Samarasekera and colleagues set out to solve a very practical problem: how to reliably measure joint angles in dynamic sports movements using wearable IMUs. Their goal was to design a ...</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/analyzing-financial-trends-kalman-filtering-for-gold-vs-bitcoin/">Analyzing Financial Trends: Kalman Filtering for Gold vs Bitcoin</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://datageeek.com/2026/08/02/analyzing-financial-trends-kalman-filtering-for-gold-vs-bitcoin/"> DataGeeek</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>

<p class="wp-block-paragraph">In their paper <em>“A Synchronized Multi‑IMU Wearable System for Tracking of Joint‑Angles in Sports Motion Analysis”</em> (<a href="https://arxiv.org/html/2607.26027v1" rel="nofollow" target="_blank">arXiv:2607.26027v1</a>), Samarasekera and colleagues set out to solve a very practical problem: <strong>how to reliably measure joint angles in dynamic sports movements using wearable IMUs</strong>. Their goal was to design a synchronized pipeline that could filter out noise, correct drift, and normalize ranges so that biomechanical signals could be trusted in real‑world conditions.</p>



<p class="wp-block-paragraph">Our goal is different but conceptually parallel: <strong>to apply the same pipeline logic to financial time‑series data</strong>. Instead of knee flexion angles, we analyze the comparative dynamics of Gold and Bitcoin. The challenge is similar — financial returns are noisy, prone to drift, and difficult to compare directly. By adapting their pipeline, we aim to extract latent trends, mitigate drift, normalize ranges, and highlight relative divergence between assets.</p>



<p class="wp-block-paragraph">The pipeline consists of four sequential stages:</p>



<ol start="1" class="wp-block-list">
<li><strong>Indirect Kalman Filtering (IKF)</strong> – extracting latent trends from noisy log returns.
<ul class="wp-block-list">
<li>State equation:</li>
</ul>
</li>
</ol>



<p class="wp-block-paragraph"><math display="block"><mrow><msub><mi>x</mi><mi>t</mi></msub><mo>=</mo><mi>F</mi><mo>⋅</mo><msub><mi>x</mi><mrow><mi>t</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>+</mo><msub><mi>w</mi><mi>t</mi></msub><mo separator="true">,</mo><mspace width="1em"></mspace><msub><mi>w</mi><mi>t</mi></msub><mo>∼</mo><mi>N</mi><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mi>Q</mi><mo stretchy="false">)</mo></mrow></math></p>



<ul class="wp-block-list">
<li>Observation equation:</li>
</ul>



<p class="wp-block-paragraph"><math display="block"><mrow><msub><mi>y</mi><mi>t</mi></msub><mo>=</mo><mi>H</mi><mo>⋅</mo><msub><mi>x</mi><mi>t</mi></msub><mo>+</mo><msub><mi>v</mi><mi>t</mi></msub><mo separator="true">,</mo><mspace width="1em"></mspace><msub><mi>v</mi><mi>t</mi></msub><mo>∼</mo><mi>N</mi><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mi>R</mi><mo stretchy="false">)</mo></mrow></math></p>



<ul class="wp-block-list">
<li>IKF separates signal from noise, with <math><mrow><mi>Q</mi></mrow></math> and <math><mrow><mi>R</mi></mrow></math> learned via maximum likelihood.</li>
</ul>



<ol start="2" class="wp-block-list">
<li><strong>Drift Mitigation via High‑Pass Filtering</strong> – removing low‑frequency bias.
<ul class="wp-block-list">
<li>High‑pass operator:</li>
</ul>
</li>
</ol>



<p class="wp-block-paragraph"><math display="block"><mrow><msubsup><mi>x</mi><mi>t</mi><mrow><mi>H</mi><mi>P</mi></mrow></msubsup><mo>=</mo><msub><mi>x</mi><mi>t</mi></msub><mo>−</mo><mfrac><mn>1</mn><mi>N</mi></mfrac><munderover><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>N</mi></munderover><msub><mi>x</mi><mrow><mi>t</mi><mo>−</mo><mi>i</mi></mrow></msub></mrow></math></p>



<ul class="wp-block-list">
<li>This ensures long‑term drift does not dominate short‑term dynamics.</li>
</ul>



<ol start="3" class="wp-block-list">
<li><strong>Range Normalization</strong> – mapping filtered values into a comparable scale.
<ul class="wp-block-list">
<li>Normalization function:</li>
</ul>
</li>
</ol>



<p class="wp-block-paragraph"><math display="block"><mrow><msub><mi>z</mi><mi>t</mi></msub><mo>=</mo><mfrac><mrow><msubsup><mi>x</mi><mi>t</mi><mrow><mi>H</mi><mi>P</mi></mrow></msubsup><mo>−</mo><mi>min</mi><mo>⁡</mo><mo stretchy="false">(</mo><msup><mi>x</mi><mrow><mi>H</mi><mi>P</mi></mrow></msup><mo stretchy="false">)</mo></mrow><mrow><mi>max</mi><mo>⁡</mo><mo stretchy="false">(</mo><msup><mi>x</mi><mrow><mi>H</mi><mi>P</mi></mrow></msup><mo stretchy="false">)</mo><mo>−</mo><mi>min</mi><mo>⁡</mo><mo stretchy="false">(</mo><msup><mi>x</mi><mrow><mi>H</mi><mi>P</mi></mrow></msup><mo stretchy="false">)</mo></mrow></mfrac><mo>⋅</mo><mn>100</mn></mrow></math></p>



<ul class="wp-block-list">
<li>This allows Gold and Bitcoin to be compared on the same 0–100 scale.</li>
</ul>



<ol start="4" class="wp-block-list">
<li><strong>Relative Notation (Directional Divergence)</strong> – highlighting when assets move in opposite directions.
<ul class="wp-block-list">
<li>Divergence indicator:</li>
</ul>
</li>
</ol>



<p class="wp-block-paragraph"><math display="block"><mrow><msub><mi>D</mi><mi>t</mi></msub><mo>=</mo><mtext>sign</mtext><mo stretchy="false">(</mo><msubsup><mi>r</mi><mi>t</mi><mrow><mi>G</mi><mi>o</mi><mi>l</mi><mi>d</mi></mrow></msubsup><mo stretchy="false">)</mo><mo>≠</mo><mtext>sign</mtext><mo stretchy="false">(</mo><msubsup><mi>r</mi><mi>t</mi><mrow><mi>B</mi><mi>T</mi><mi>C</mi></mrow></msubsup><mo stretchy="false">)</mo></mrow></math></p>



<ul class="wp-block-list">
<li>If true, shaded regions show divergence; if false, alignment.</li>
</ul>



<h3 class="wp-block-heading">Why This Matters</h3>



<ul class="wp-block-list">
<li>For the biomechanics researchers, the pipeline meant <strong>trustworthy joint‑angle tracking</strong>.</li>



<li>For us, the same architecture means <strong>trustworthy comparative trend analysis</strong> between financial assets.</li>



<li>In both cases, the pipeline’s strength lies in its modularity: IKF for latent signal extraction, high‑pass filtering for drift control, normalization for comparability, and relative notation for divergence detection.</li>
</ul>



<h2 class="wp-block-heading">✦ R Packages in Our Pipeline</h2>



<p class="wp-block-paragraph">To make this pipeline reproducible and transparent, we rely on a set of R packages. Each package plays a specific role in the architecture:</p>



<ol start="1" class="wp-block-list">
<li><strong>tidyverse</strong>
<ul class="wp-block-list">
<li>Purpose: Data manipulation and wrangling.</li>



<li>Functions: <code>mutate</code>, <code>rename</code>, <code>inner_join</code>, <code>drop_na</code>.</li>



<li>Why: Provides a clean grammar for transforming raw financial data into structured time‑series.</li>
</ul>
</li>



<li><strong>tidyquant</strong>
<ul class="wp-block-list">
<li>Purpose: Financial data acquisition and transformation.</li>



<li>Functions: <code>tq_get</code> (download asset prices), <code>tq_transmute</code> (compute log returns).</li>



<li>Why: Bridges tidyverse with financial APIs, enabling reproducible market data pipelines.</li>
</ul>
</li>



<li><strong>KFAS</strong>
<ul class="wp-block-list">
<li>Purpose: State‑space modeling and Kalman filtering.</li>



<li>Functions: <code>SSModel</code> (define state‑space model), <code>fitSSM</code> (MLE parameter estimation), <code>KFS</code> (Kalman smoothing).</li>



<li>Why: Implements the mathematical backbone of IKF, separating latent trends from noise.</li>
</ul>
</li>



<li><strong>zoo</strong>
<ul class="wp-block-list">
<li>Purpose: Rolling window operations.</li>



<li>Functions: <code>rollmean</code>.</li>



<li>Why: Used for high‑pass filtering by subtracting rolling averages, mitigating drift.</li>
</ul>
</li>



<li><strong>scales</strong>
<ul class="wp-block-list">
<li>Purpose: Normalization and rescaling.</li>



<li>Functions: <code>rescale</code>.</li>



<li>Why: Maps filtered trends into a 0–100 range, enabling comparability across assets.</li>
</ul>
</li>



<li><strong>ggbraid</strong>
<ul class="wp-block-list">
<li>Purpose: Divergence visualization.</li>



<li>Functions: <code>geom_braid</code>.</li>



<li>Why: Highlights periods of divergence between Gold and Bitcoin with shaded regions.</li>
</ul>
</li>



<li><strong>ggplot2 (via tidyverse)</strong>
<ul class="wp-block-list">
<li>Purpose: Visualization.</li>



<li>Functions: <code>geom_line</code>, <code>labs</code>, <code>theme_classic</code>.</li>



<li>Why: Provides the plotting framework for presenting normalized high‑pass Kalman trends.</li>
</ul>
</li>
</ol>


<pre>
library(tidyverse)
library(tidyquant)
library(KFAS)
library(ggbraid)

# --- Step 1: Log returns ---
gold &lt;- tq_get(&quot;GC=F&quot;, from = &quot;2024-01-01&quot;) %&gt;%
  tq_transmute(select = close,
               mutate_fun = periodReturn,
               period = &quot;daily&quot;,
               type = &quot;log&quot;)

btc &lt;- tq_get(&quot;BTC-USD&quot;, from = &quot;2024-01-01&quot;) %&gt;%
  tq_transmute(select = close,
               mutate_fun = periodReturn,
               period = &quot;daily&quot;,
               type = &quot;log&quot;)

df &lt;- gold %&gt;%
  rename(ret_gold = daily.returns) %&gt;%
  inner_join(btc %&gt;% rename(ret_btc = daily.returns), by=&quot;date&quot;) %&gt;%
  drop_na()

# --- Step 2: IKF (Kalman filter) ---
model_gold &lt;- SSModel(df$ret_gold ~ SSMtrend(1, Q = list(NA)), H = NA)
model_btc  &lt;- SSModel(df$ret_btc  ~ SSMtrend(1, Q = list(NA)), H = NA)

fit_gold &lt;- fitSSM(model_gold, inits = c(log(var(df$ret_gold)), log(var(df$ret_gold))))
fit_btc  &lt;- fitSSM(model_btc,  inits = c(log(var(df$ret_btc)),  log(var(df$ret_btc))))

kf_gold &lt;- KFS(fit_gold$model, smoothing = c(&quot;state&quot;))
kf_btc  &lt;- KFS(fit_btc$model,  smoothing = c(&quot;state&quot;))

trend_gold &lt;- as.numeric(kf_gold$alphahat)
trend_btc  &lt;- as.numeric(kf_btc$alphahat)

# --- Step 3: High-pass filter (remove low-frequency drift) ---
hp_gold &lt;- trend_gold - zoo::rollmean(trend_gold, k=30, fill=NA, align=&quot;right&quot;)
hp_btc  &lt;- trend_btc  - zoo::rollmean(trend_btc,  k=30, fill=NA, align=&quot;right&quot;)

# --- Step 4: Range normalization ---
gold_norm &lt;- scales::rescale(hp_gold, to=c(0,100))
btc_norm  &lt;- scales::rescale(hp_btc,  to=c(0,100))

# --- Step 5: Relative notation (directional divergence) ---
df_norm &lt;- df %&gt;%
  mutate(
    gold_norm = gold_norm,
    btc_norm  = btc_norm,
    sign_gold = sign(ret_gold),
    sign_btc  = sign(ret_btc),
    divergence = sign_gold != sign_btc
  )

# --- Plot ---
ggplot(df_norm, aes(x=date)) +
  geom_line(aes(y=gold_norm, color=&quot;Gold&quot;), linewidth=1.2) +
  geom_line(aes(y=btc_norm, color=&quot;Bitcoin&quot;), linewidth=1.2) +
  geom_braid(aes(ymin=gold_norm, ymax=btc_norm, fill=divergence), alpha=0.3) +
  scale_color_manual(values=c(&quot;Gold&quot;=&quot;#FFD700&quot;, &quot;Bitcoin&quot;=&quot;#1E3A8A&quot;),
                     name = &quot;&quot;) +
  scale_fill_manual(values=c(&quot;TRUE&quot;=&quot;#FF4C4C&quot;, &quot;FALSE&quot;=&quot;#87CEFA&quot;),
                    name = &quot;Divergence&quot;) +
  scale_y_continuous(limits=c(0,100)) +
  labs(title=&quot;Gold vs Bitcoin: Kalman-Filtered High-Pass Trends&quot;,
       subtitle=&quot;Directional divergence highlighted with shaded regions&quot;,
       x=&quot;&quot;, y=&quot;Normalized High-Pass Kalman Trend&quot;) +
  theme_classic(base_family = &quot;Roboto Slab&quot;) +
  theme(
    legend.position=&quot;bottom&quot;,
    legend.title=element_text(size=12, face=&quot;bold&quot;),
    legend.text=element_text(size=10),
    plot.title=element_text(size=16, face=&quot;bold&quot;),
    plot.subtitle=element_text(size=12),
    axis.title=element_text(size=12, face=&quot;bold&quot;),
    axis.text=element_text(size=10),
    panel.grid.minor=element_blank()
  )

</pre>


<figure data-wp-context="{"imageId":"6a6f3e4d5975b"}" data-wp-interactive="core/image" data-wp-key="6a6f3e4d5975b" class="wp-block-image size-full wp-lightbox-container"><img data-attachment-id="12432" data-permalink="https://datageeek.com/2026/08/02/analyzing-financial-trends-kalman-filtering-for-gold-vs-bitcoin/kalman/" data-orig-file="https://i1.wp.com/datageeek.com/wp-content/uploads/2026/08/kalman-1.png?w=578&#038;ssl=1" data-orig-size="948,683" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","alt":""}" data-image-title="kalman" data-image-description="" data-image-caption="" data-large-file="https://i1.wp.com/datageeek.com/wp-content/uploads/2026/08/kalman-1.png?w=578&#038;ssl=1?w=948" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://i1.wp.com/datageeek.com/wp-content/uploads/2026/08/kalman-1.png?w=578&#038;ssl=1" alt="" class="wp-image-12432" data-recalc-dims="1" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h2 class="wp-block-heading"><img src="https://i2.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f539.png?w=578&#038;ssl=1" alt="&#x1f539;" class="wp-smiley" style="height: 1em; max-height: 1em;" data-recalc-dims="1" /> Conclusion</h2>



<p class="wp-block-paragraph">By adapting the IKF pipeline from the sports biomechanics paper, we demonstrate how <strong>state‑space filtering</strong>, drift mitigation, and normalization can reveal comparative dynamics among financial assets. This modular approach is reproducible and extensible to other domains where latent trends and divergence matter.</p>



<p class="wp-block-paragraph"></p>

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://datageeek.com/2026/08/02/analyzing-financial-trends-kalman-filtering-for-gold-vs-bitcoin/"> DataGeeek</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/analyzing-financial-trends-kalman-filtering-for-gold-vs-bitcoin/">Analyzing Financial Trends: Kalman Filtering for Gold vs Bitcoin</a>]]></content:encoded>
					
		
		<enclosure url="https://datageeek.com/wp-content/uploads/2026/08/kalman_featured-3.png" length="0" type="" />
<enclosure url="https://1.gravatar.com/avatar/db5e3f9ef188ea98fe38ab05c5a3fad9fb52fe3472715a8fc02f7ea41731f77c?s=96&#038;d=identicon&#038;r=G" length="0" type="" />
<enclosure url="https://datageeek.com/wp-content/uploads/2026/08/kalman-1.png" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402923</post-id>	</item>
		<item>
		<title>The Future of Programming Looks Like Its Past or Why I build T</title>
		<link>https://www.r-bloggers.com/2026/08/the-future-of-programming-looks-like-its-past-or-why-i-build-t/</link>
		
		<dc:creator><![CDATA[Econometrics and Free Software]]></dc:creator>
		<pubDate>Sun, 02 Aug 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://b-rodrigues.github.io/posts/2026-08-02-t_devlog.html</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>This is a post based on two other posts I wrote for LinkedIn. It has become quite long.</p>
<p>AI Won’t Save People From Work They Never Thought to Automate<br />
I’m a fairly optimistic person, but when it comes to AI adoption and how it will be gene...</p></div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/the-future-of-programming-looks-like-its-past-or-why-i-build-t/">The Future of Programming Looks Like Its Past or Why I build T</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://b-rodrigues.github.io/posts/2026-08-02-t_devlog.html"> Econometrics and Free Software</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
 




<div style="text-align: center;">
<p>
<a> <img src="https://i0.wp.com/b-rodrigues.github.io/assets/img/tlogo.png?w=578&#038;ssl=1" style="width: 50%; height: auto;" data-recalc-dims="1"> </a>
</p>
</div>
<p><em>This is a post based on two other posts I wrote for LinkedIn. It has become quite long.</em></p>
<section id="ai-wont-save-people-from-work-they-never-thought-to-automate" class="level2">
<h2 class="anchored" data-anchor-id="ai-wont-save-people-from-work-they-never-thought-to-automate">AI Won’t Save People From Work They Never Thought to Automate</h2>
<p>I’m a fairly optimistic person, but when it comes to AI adoption and how it will be generating billions in increased GDP I’m more skeptical. Not that AI is not capable: on the contrary, I think that for all intents and purposes, even the models from 6 months ago are more than capable enough to perform a majority of white collar tasks, including programming. No, I think the issue is the same I’ve observed many times over my years on this God’s green earth, and that is that there are people who see computers as tools for doing tasks and people who see computers as systems that can be taught to do tasks.</p>
<p>Consider two people using Excel. Both have used it for ten years.</p>
<p>Jim receives a monthly report and manually copies data between sheets, formats cells, and updates numbers. He’s learned the workflow and can execute it efficiently. He’s essentially performing the task using a computer as he would with a pen and paper. He’s doing procedural work. That’s his job, and he’s good at it.</p>
<p>Bill, on the other hand, asks himself the question: “Why am I doing this every month? Is my job actually about moving data around? Or is it something else? What is my purpose?” Now this may seem overly philosophical when the topic at hand is moving data around in Excel to increase shareholder value, but nonetheless, these questions are the right ones to ask. So Bill starts seeing his computer not as a tool that simply replaced pen and paper, but as something he can teach to perform tasks.</p>
<p>Bill learns about formulas. Bill learns about pivot tables. Using the free tier of an LLM he makes it write macros. He then even creates styles for Word instead of changing the headers manually each time.</p>
<p>The difference is not technical ability. Both Jim and Bill can operate Excel and Word. But the difference is the mental model. Jim sees the computer as a digital version of pen and paper. It is a place where work happens. Bill sees the computer as a machine that can execute rules. It is a place where work can be transformed into a repeatable system.</p>
<p>Bill has an automation mindset. People with an automation mindset naturally ask different questions. Instead of:</p>
<p>“How do I complete this task?”</p>
<p>they ask:</p>
<ul>
<li>“This fucking sucks and surely there’s a better way of doing it?”</li>
</ul>
<p>Instead of:</p>
<ul>
<li>“How do I make this report?”</li>
</ul>
<p>they ask:</p>
<ul>
<li>“How can this report generate itself and fuck off?”</li>
</ul>
<p>Instead of:</p>
<ul>
<li>“How do I process these 1000 files?”</li>
</ul>
<p>they ask:</p>
<ul>
<li>“How can I write a process that handles any number of files?”</li>
</ul>
<p>The key shift is recognizing that anything you do is required to follow rules, and these rules are mostly implicit and invisible. It is moving from thinking about individual actions to thinking about the underlying rules that matters.</p>
<p>Computers are powerful because they are not just faster versions of humans. Their real advantage is that they can execute instructions that follow rules repeatedly, consistently, and at scale, but you gotta provide them with the rules.</p>
</section>
<section id="the-real-barrier-to-ai-automation-mindset-tools-and-culture" class="level2">
<h2 class="anchored" data-anchor-id="the-real-barrier-to-ai-automation-mindset-tools-and-culture">The Real Barrier to AI Automation: Mindset, Tools, and Culture</h2>
<p>A common assumption is that AI will democratize automation because people no longer need to know how to program, which is certainly true (to some extent). AI dramatically lowers the technical barrier. Someone can now describe a workflow in natural language and get help creating scripts, automations, or processes.</p>
<p>But there is a more fundamental barrier: people have to imagine that automation is possible in the first place!</p>
<p>Someone who has never thought about programming will not suddenly become an automation architect just because they have access to an AI assistant.</p>
<ul>
<li>Jim may use AI to write an email faster.</li>
<li>Jim may use AI to summarize a document.</li>
<li>Jim may use AI to answer a question.</li>
</ul>
<p>Those are useful improvements.</p>
<p>But Bill is playing another game entirely. He’s thinking about implicit rules, and how to make them explicit (which, by the way, can also be done with AI!). So he’s rubber ducking with Claude and asking it:</p>
<ul>
<li>“Why does this task exist at all?”</li>
<li>“Could this entire workflow disappear?”</li>
<li>“Could you (Claude) write a Python script/Excel Macro to run this every week?”</li>
</ul>
<p>While certainly AI lowers the cost of building systems, it does not automatically teach people to think in systems.</p>
<p>It is not Jim’s fault though. This difference in mindset can even be seen in operating systems. Historically, Windows has emphasized graphical workflows. The philosophy is often: “There is a tool or button for every task. This Word document just looks like an actual sheet of paper, so treat it as such. This Excel workbook just looks like an actual ledger your grandpa used to use, so treat it as such.” Linux and Unix come from a different tradition: “Everything is a program. Programs can be combined. You pass data from program to program by streams of text. Text is the fundamental unit of information.”</p>
<p>A Linux user solving a repetitive problem often starts with a command, then turns that command into a script, then schedules that script to run automatically.</p>
<p>The progression is natural:</p>
<p>Manual action → command → script → automated system.</p>
<p>Windows has powerful automation capabilities too. PowerShell is an extremely capable scripting environment. But for too long, Windows’ main target audience was (and still is) the white collar office drone. Even though it is absolutely possible to automate tasks on Windows, the culture now is not one of automation. And technology alone does not create culture.</p>
<p>There are many such examples. Consider using a regular text editor like VS Code versus something like Vim. With regular text editors, you essentially use your computer as a fancy pen and paper. With Vim, you manipulate text and think about ranges and how to operate on them using macros. Very different mental models. In fact, they’re so different that trying to explain Vim to someone not familiar with it is practically impossible. People can only truly get it if they try it and keep using it for some time. And it’s the same thing with data analysis: using Excel vs R for example. The surrounding culture matters. If users grow up thinking:</p>
<ul>
<li>“The computer is a place where I click through tasks,”</li>
</ul>
<p>they will rarely ask:</p>
<ul>
<li>“How can the computer do this task for me?”</li>
</ul>
<p>The tool exists. The mindset does not.</p>
</section>
<section id="transforming-organizations-rewarding-work-elimination" class="level2">
<h2 class="anchored" data-anchor-id="transforming-organizations-rewarding-work-elimination">Transforming Organizations: Rewarding Work Elimination</h2>
<p>Many companies are approaching AI transformation as a training problem: teach employees how to use AI tools. But the deeper challenge is a thinking problem: teach employees how to identify opportunities for automation. The most valuable AI employees will not necessarily be the people who write the cleverest prompts. They will be the people who notice:</p>
<ul>
<li>“Everyone spends two hours every week doing this repetitive process.”</li>
<li>“This information is copied manually between systems.”</li>
<li>“This decision follows a predictable set of rules. These rules are not written down anywhere, but they exist.”</li>
<li>“This workflow exists only because nobody questioned it.”</li>
</ul>
<p>Those people are the ones who will transform organizations, and organizations need to create an incentive structure where people are rewarded for eliminating work, not for performing more work. The irony is that many organizations say they want efficiency but reward visible effort. True AI transformation requires rewarding people who make themselves unnecessary.</p>
<p>The biggest advantage of AI will not come from people who use it as a faster assistant. It will come from people who use it as a way to redesign work. The question that separates the old way of working from the new one is simple:</p>
<ul>
<li>“Why am I doing this manually at all?”</li>
</ul>
<p>AI is powerful because it makes accessing automation easier than ever before. But the greatest gains will go to those who already understand the fundamental idea behind computers:</p>
<p><strong>A computer is not just a tool for performing tasks!</strong></p>
<p>It is a machine for turning ideas, rules, and processes into systems that run.</p>
</section>
<section id="jupyter-notebooks-and-interactive-data-analysis-are-dead-one-can-hope" class="level2">
<h2 class="anchored" data-anchor-id="jupyter-notebooks-and-interactive-data-analysis-are-dead-one-can-hope">Jupyter Notebooks (and Interactive Data Analysis) Are Dead (one can hope)</h2>
<p>Now how do these observations translate to our work as data scientists?</p>
<p>I’ve spent years watching data science workflows evolve, and I keep coming back to the same conclusion:</p>
<p>Jupyter notebooks are making data science and statistics worse. I’d even go so far as to argue that interactive data analysis may be the wrong mental model altogether.</p>
<p>Let’s start with notebooks. If you’ve been reading my work these past years, you know I’m not fond of them.</p>
<p>They encourage messy, non-reproducible “spaghetti” code. They mix data, business logic, and results into a single file (something most of us would never accept in an Excel spreadsheet, yet somehow tolerate in an .ipynb). They’re also not plain text, which makes version control, code review, and collaboration unnecessarily painful, often requiring dedicated tooling just to work around the format.</p>
<p>Joel Grus said it best years ago in his classic <em>I Don’t Like Notebooks</em> talk (go watch it on youtube, it’s great). Very little has changed since then.</p>
<p>So why did notebooks become so dominant?</p>
<p>Because Python’s scientific computing tooling was simply that bad for a long time. Spyder wasn’t great. Installing Python packages was (and, to some extent, still is) an absolute clown show. <code>uv</code> has dramatically improved the experience, but it can’t solve the deeper structural issues of PyPI.</p>
<p>From the mid-2000s through the early 2010s, spinning up a Jupyter server with a curated set of pre-installed packages was often the only practical way for institutions to provide working Python environments to their users. Unlike R, which had RStudio, Python never had a truly first-class IDE built specifically for scientific computing. So a whole generation of data scientists grew up on Jupyter and now teach on Jupyter and force their juniors to use Jupyter. Big mistake! Even without AI, there’s no reason to keep using notebooks. Positron is excellent, and VS Code can be configured into a capable data science environment. But AI may end up making the entire IDE debate irrelevant (of course, us Emacs or Vim chads have solved this since decades).</p>
<p>AI agents thrive on plain text, which also happens to be the simplest and most enduring interface in computing, especially in the Unix/Linux world.</p>
<p>Jupyter notebooks, by contrast, are JSON documents rather than plain text (and the json format itself would actually not be an issue for agents, to be fair). But notebooks have many longstanding problems (hidden state, side effects, and non-linear execution) which are exactly the kinds of things that make life difficult for AI agents. AI systems struggle with implicit state and unpredictable execution. Tools and interfaces that deliberately minimize these issues (like plain-text scripts, explicit pipelines, immutable workflows) don’t just make life easier for humans; they make it easier for AI as well.</p>
<p>If AI becomes central to software development (which it will), I think we’ll see a resurgence of simple text-based workflows.</p>
<p>A notebook is essentially a recording of a conversation between a human and a computer:</p>
<pre>Run cell.
Inspect output.
Modify.
Run again.
Oops.
Restart kernel.
Run all.</pre>
<p>It’s procedural and interactive, and it’s completely pointless when the coding is being done by an AI agent. Just think about it: imagine we’re back in 2010, and you hire some data science consultants to analyse some data. Do you care to see which tools they used for the analysis? You might be interested in the source code of the analysis itself, but why would you care if they used notebooks or plain text scripts? This is essentially the same here. People might say “well I care because I want to collaborate with AI”, and that may be true, but I’m willing to bet that we’re going to move more towards what makes AI efficient (plain text) and move away from what humans like (notebooks if you have shit taste). We start to see it already in the tooling that is being developed and offered to developers: we’ve started with AI agents embedded in text editors doing auto-complete to “harnesses” that edit the code for you and show you the diffs.</p>
<p>That brings me back to the idea of interactive data analysis. Increasingly, I think the workflow itself may be flawed.</p>
<p>To be clear, there is real value in exploring data: filtering, slicing, visualizing, trying different models, testing hypotheses, tweaking graphs. The problem is that this exploratory process usually produces a chaotic script that eventually has to be rewritten before it can be put into production. We accept this rewrite as part of the job, but ideally we shouldn’t have to.</p>
<p>AI changes that equation.</p>
<p>Humans can continue exploring data in messy, experimental code while AI agents continuously refactor that exploration into clean, modular, production-ready pipelines. Instead of treating exploration and production as two separate phases, we can have AI bridge the gap in real time.</p>
</section>
<section id="introducing-t-describing-systems-constraints-and-intent" class="level2">
<h2 class="anchored" data-anchor-id="introducing-t-describing-systems-constraints-and-intent">Introducing T: Describing Systems, Constraints, and Intent</h2>
<p>Those two ideas (that plain text is still the best interface we have, and that human-agent collaboration will fundamentally reshape how we build software) are the foundation of the domain-specific language I’m working on, T.</p>
<p>Also, I’m betting that the history of computing will keep on repeating itself, and this history as always about raising the level of abstraction. In the 1980s and 1990s, everyone wanted programming to become <em>more interactive</em>. We got IDEs, GUIs, notebooks, drag-and-drop workflows, visual programming, WYSIWYG editors. The assumption was that making computers more like humans was the future. We went from describing exactly what the CPU should do to describing data transformations with modern functional programming.</p>
<p>With AI, we are increasingly focusing on describing <strong>systems</strong>, <strong>constraints</strong>, and <strong>intent</strong>.</p>
<p>We’re rediscovering that plain text, explicit representations, and declarative specifications are incredibly powerful: not because humans suddenly prefer them (some nerds do, see NixOS), but because <em>both humans and AI can reason about them</em>. Git can diff them. Compilers can analyze them. LLMs can transform them. They compose naturally.</p>
<p>So the future may look surprisingly like the past: not because we’ve failed to innovate, but because we’ve rediscovered that the oldest Unix philosophy was pointing in the right direction all along:</p>
<blockquote class="blockquote">
<p>Everything should have an explicit, textual representation that can be composed into larger systems.</p>
</blockquote>
<p>For example, instead of writing:</p>
<pre>for ...
    ...</pre>
<p>you tell some AI-agent in voice mode:</p>
<blockquote class="blockquote">
<p>Here’s my data. These transformations must happen. These invariants must hold. This pipeline should be reproducible.</p>
</blockquote>
<p>Let’s go back to the intro: Jim thinks in <strong>tasks</strong>.</p>
<blockquote class="blockquote">
<p>“I need to copy these numbers.”</p>
</blockquote>
<p>Bill thinks in <strong>rules</strong>.</p>
<blockquote class="blockquote">
<p>“These numbers are generated according to these rules.”</p>
</blockquote>
<p>When using an AI, you need to go one step further and think about systems and design. Once the system or the design of your project is explicit, generating Python, R, SQL, Bash, DuckDB, Polars, Spark, or whatever becomes almost an implementation detail.</p>
<p>This is the main design principle behind T.</p>
<p>T is an experimental, reproducibility-by-design DSL for polyglot data science. It provides a functional, immutable language for constructing composable micropipelines: first-class, introspectable computation graphs that coordinate R, Python, Julia, Quarto, and Shell execution within a unified system. Pipelines in T are not configuration artifacts but executable program structures with explicit dataflow, typed nodes, and content-addressed outputs. I’ve talked about it already <a href="https://brodrigues.co/posts/2026-04-03-tproject.html" rel="nofollow" target="_blank">here</a>.</p>
<p>The main idea is that you <strong>will not</strong> write any T code. An AI agent should do it. And to achieve this, everything humans can do with T (running code, running tests, looking at error messages, etc) can also be done by AI agents. Agents can run the code and get feedback in json format. Error messages can also be surfaced using json. There is a whole “agentic” way of using T that is first-class.</p>
<p>Built on Nix, T integrates declarative environment management and deterministic builds at the language level. Every node runs in its own hermetic sandbox. Reproducibility isn’t something you configure; it’s something you can’t opt out of. Data moves via Apache Arrow. The actual data analysis code is still written in R, Python or Julia. T “merely” owns the data boundaries and efficiently coordinates the different nodes written in different languages seamlessly. Models can be trained in R or Python and evaluated natively in T via PMML or ONNX. The language is strictly functional: no mutable state, errors as values, tidyverse-inspired verbs for exploration in the REPL, then promotion into production pipelines.</p>
<p>Its source is 100% AI-generated and thoroughly tested. Starting a T project will ship an <code>AGENTS.md</code> and tiered language references so LLMs get the exact context they need. Intent blocks let you embed the “why.” <code>t check</code> is milliseconds and checks the structural correctness of the pipeline; builds are cached and content-addressed.</p>
<p>If T succeeds, I don’t think it should be framed as “another programming language.” It should be framed as <strong>a language for describing data science pipelines</strong>. Check it out <a href="https://github.com/b-rodrigues/tlang" rel="nofollow" target="_blank">here</a> or the <a href="https://tstats-project.org/" rel="nofollow" target="_blank">website</a>.</p>
<p>AI won’t eliminate the need to think computationally; it will make computational thinking more valuable than ever. The syntax is becoming cheaper. The implementation is becoming easier. What remains scarce is the ability to recognize systems where others only see tasks. That’s why I think the future of programming looks so much like its past: explicit representations, declarative descriptions, and composable systems remain the best way to communicate intent.</p>


</section>

 
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://b-rodrigues.github.io/posts/2026-08-02-t_devlog.html"> Econometrics and Free Software</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/the-future-of-programming-looks-like-its-past-or-why-i-build-t/">The Future of Programming Looks Like Its Past or Why I build T</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402948</post-id>	</item>
		<item>
		<title>Little useless-useful R functions – Honest geographical location signposts</title>
		<link>https://www.r-bloggers.com/2026/08/little-useless-useful-r-functions-honest-geographical-location-signposts/</link>
		
		<dc:creator><![CDATA[tomaztsql]]></dc:creator>
		<pubDate>Sat, 01 Aug 2026 16:09:59 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">http://tomaztsql.wordpress.com/?p=11201</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> We have all seen colourful signposts with great cities and their distances – how far each is from this current standpoint. And fundamental question is, how correct these distances are? Or even, one should ask, how honest a particular signpost…Read more ›</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/little-useless-useful-r-functions-honest-geographical-location-signposts/">Little useless-useful R functions – Honest geographical location signposts</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://tomaztsql.wordpress.com/2026/08/01/little-useless-useful-r-functions-honest-geographical-location-signposts/"> R – TomazTsql</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>

<p class="wp-block-paragraph">We have all seen colourful signposts with great cities and their distances –  how far each is from this current standpoint.</p>



<figure class="wp-block-image size-large"><a href="https://i1.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/08/image.png?ssl=1" rel="nofollow" target="_blank"><img loading="lazy" data-attachment-id="11205" data-permalink="https://tomaztsql.wordpress.com/2026/08/01/little-useless-useful-r-functions-honest-geographical-location-signposts/image-348/" data-orig-file="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image.png" data-orig-size="877,801" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","alt":""}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image.png?w=605" src="https://i1.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/08/image.png?w=450&#038;ssl=1" alt="" class="wp-image-11205" srcset_temp="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image.png 877w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image.png?w=150 150w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image.png?w=300 300w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image.png?w=768 768w" sizes="(max-width: 877px) 100vw, 877px" data-recalc-dims="1" /></a></figure>



<p class="wp-block-paragraph">And fundamental question is, how correct these distances are? Or even, one should ask, how honest a particular signpost is, regarding the current standpoint.</p>



<p class="wp-block-paragraph">So let’s put this utterly most fundamental question to the test <img src="https://i1.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png?w=578&#038;ssl=1" alt="&#x1f642;" class="wp-smiley" style="height: 1em; max-height: 1em;" data-recalc-dims="1" /> And since it is vacation time, you can grab the R code and check it yourself <img src="https://i1.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png?w=578&#038;ssl=1" alt="&#x1f642;" class="wp-smiley" style="height: 1em; max-height: 1em;" data-recalc-dims="1" /></p>



<p class="wp-block-paragraph">Image stumbling upon the post and wanted to check if this post is really relevant for this location. It can be a photo from other side of the world, hanging in the lobby of your holiday hotel <img src="https://i1.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png?w=578&#038;ssl=1" alt="&#x1f642;" class="wp-smiley" style="height: 1em; max-height: 1em;" data-recalc-dims="1" /> And this sure ain’t honest signpost <img src="https://i1.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png?w=578&#038;ssl=1" alt="&#x1f642;" class="wp-smiley" style="height: 1em; max-height: 1em;" data-recalc-dims="1" /></p>



<p class="wp-block-paragraph">The R code iterates through each city, finds matching points (where all circles meet) and searches for the nearest location. It uses <a href="https://www.openstreetmap.org/" rel="nofollow" target="_blank">OpenStreetMap</a> (short: OSM) to extract all the geolocations and looks for possible intersections of all points</p>



<pre>
geocode_city &lt;- function(city_name) {
 
  url &lt;- modify_url(
    &quot;https://nominatim.openstreetmap.org/search&quot;,
    query = list(
      q       = city_name,
      format  = &quot;json&quot;,
      limit   = 1
    )
  )
  
  resp &lt;- tryCatch(
    GET(url, user_agent(&quot;PointingSignFinder/1.0 (R script)&quot;)),
     error = function(e) {
       cat(&quot; Error on endpoint&quot;)
       return(NULL)
     }
  )
  
  if (is.null(resp) || http_error(resp)) {
    cat(&quot; Error on http\n&quot;)
    return(NULL)
  }
  
  result &lt;- fromJSON(content(resp, as = &quot;text&quot;, encoding = &quot;UTF-8&quot;))
  
  if (length(result) == 0) {
    cat(&quot;Error on result&quot;)
    return(NULL)
  }
  
  lat &lt;- as.numeric(result$lat[1])
  lon &lt;- as.numeric(result$lon[1])
  cat(sprintf(&quot; found: %.4f°, %.4f°\n&quot;, lat, lon))
  
  Sys.sleep(1.1)
  
  list(lat = lat, lon = lon, display_name = result$display_name[1])
}


sign_location_finder &lt;- function(cities,
                                 distances,
                                 tolerance = 50,
                                 coarse_res = 0.2,
                                 fine_res   = 0.02,
                                 nearby_radius = 200,
                                 nearby_min_pop = 100000) {
  
  stopifnot(length(cities) == length(distances))
  stopifnot(length(cities) &gt;= 2)
  
  cat(&quot;Step 1: Geocoding cities\n&quot;)
  coords &lt;- lapply(cities, geocode_city)
  
  failed &lt;- which(sapply(coords, is.null))
  if (length(failed) &gt; 0) {
    stop(sprintf(&quot;Location not founc: %s&quot;, paste(cities[failed], collapse = &quot;, &quot;)))
  }
  
  sign_data &lt;- data.frame(
    city    = cities,
    lat     = sapply(coords, `[[`, &quot;lat&quot;),
    lon     = sapply(coords, `[[`, &quot;lon&quot;),
    dist_km = distances
  )


print(sign_data[, c(&quot;city&quot;, &quot;lat&quot;, &quot;lon&quot;, &quot;dist_km&quot;)])
  
max_dist_deg &lt;- max(sign_data$dist_km) / 111
lat_min &lt;- min(sign_data$lat) - max_dist_deg - 5
lat_max &lt;- max(sign_data$lat) + max_dist_deg + 5
lon_min &lt;- min(sign_data$lon) - max_dist_deg * 2 - 5
lon_max &lt;- max(sign_data$lon) + max_dist_deg * 2 + 5
  
 
lat_min &lt;- max(lat_min, -85)
lat_max &lt;- min(lat_max,  85)
lon_min &lt;- max(lon_min, -180)
lon_max &lt;- min(lon_max,  180)
  
cat(sprintf(&quot;\nStep 2: Search bounding box: lat [%.1f, %.1f], lon [%.1f, %.1f]\n&quot;,
              lat_min, lat_max, lon_min, lon_max))
  
  
  score_point &lt;- function(plat, plon) {
    diffs &lt;- sapply(seq_len(nrow(sign_data)), function(i) {
      d &lt;- distHaversine(
        c(plon, plat),
        c(sign_data$lon[i], sign_data$lat[i])
      ) / 1000
      abs(d - sign_data$dist_km[i])
    })
    max(diffs)
  }
  
  
  cat(sprintf(&quot;\nStep 3: Search the grid (%.2f° resolution)...\n&quot;, coarse_res))
  grid &lt;- expand.grid(
    lat = seq(lat_min, lat_max, by = coarse_res),
    lon = seq(lon_min, lon_max, by = coarse_res)
  )
  cat(sprintf(&quot;Checking %d grid points...\n&quot;, nrow(grid)))
  grid$score &lt;- mapply(score_point, grid$lat, grid$lon)
  
  candidates &lt;- grid[grid$score &lt;= tolerance, ]
  cat(sprintf(&quot; Found %d candidate cells within ±%d km tolerance.\n&quot;,
              nrow(candidates), tolerance))
  
  coarse_best &lt;- grid[which.min(grid$score), ]
  
  fine_grid &lt;- expand.grid(
    lat = seq(coarse_best$lat - 1, coarse_best$lat + 1, by = fine_res),
    lon = seq(coarse_best$lon - 1, coarse_best$lon + 1, by = fine_res)
  )
  fine_grid$score &lt;- mapply(score_point, fine_grid$lat, fine_grid$lon)
  best &lt;- fine_grid[which.min(fine_grid$score), ]
  
  cat(sprintf(&quot;\n&gt;&gt;&gt; Estimated  locations:\n&quot;))
  cat(sprintf(&quot;    Latitude  : %.4f°\n&quot;, best$lat))
  cat(sprintf(&quot;    Longitude : %.4f°\n&quot;, best$lon))
  cat(sprintf(&quot;    Max error : ±%.1f km\n&quot;, best$score))
  cat(sprintf(&quot;    Google Maps: https://www.google.com/maps?q=%.4f,%.4f\n&quot;, best$lat, best$lon))
  
  cat(sprintf(&quot;\nStep 5: Nearby cities (within %d km, pop &gt; %s)...\n&quot;,
              nearby_radius, format(nearby_min_pop, big.mark = &quot;,&quot;)))
  
  world_cities &lt;- world.cities
  nearby &lt;- world_cities |&gt;
    filter(pop &gt; nearby_min_pop) |&gt;
    mutate(
      dist_to_sign = distHaversine(
        cbind(long, lat),
        c(best$lon, best$lat)
      ) / 1000
    ) |&gt;
    filter(dist_to_sign &lt;= nearby_radius) |&gt;
    arrange(dist_to_sign) |&gt;
    select(name, country.etc, lat, long, pop, dist_to_sign) |&gt;
    head(10)
  
  if (nrow(nearby) &gt; 0) {
    cat(&quot;\n  Cities found:\n&quot;)
    print(nearby, digits = 4)
    cat(sprintf(&quot;\n  Nearest: %s, %s (%.1f km away)\n&quot;,
                nearby$name[1], nearby$country.etc[1], nearby$dist_to_sign[1]))
  } else {
    cat(&quot;No major locations found in vicinity!&quot;)
  }
  

}</pre>



<p class="wp-block-paragraph">So now, that we understand the useless problem, we can put this to the test <img src="https://i1.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png?w=578&#038;ssl=1" alt="&#x1f642;" class="wp-smiley" style="height: 1em; max-height: 1em;" data-recalc-dims="1" /></p>



<p class="wp-block-paragraph"></p>


<div class="wp-block-code">
	<div class="cm-editor">
		<div class="cm-scroller">
			
<pre>
# sample 2 - real with correct distances calculater from#  https://www.distancefromto.net/  &quot;air distance&quot;# result must be Ljubljana, Sloveniaresult &lt;- sign_location_finder(  cities    = c(&quot;Koper&quot;, &quot;Celje&quot;, &quot;Maribor&quot;, &quot;Kranj&quot;),  distances = c(83, 61, 104, 24),  tolerance = 20) </pre>
		</div>
	</div>
</div>


<p class="wp-block-paragraph">In this case I have entered the correct air distances and there should be a location present – which is capital of Slovenia – Ljubljana.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><a href="https://i2.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/08/image-1.png?ssl=1" rel="nofollow" target="_blank"><img loading="lazy" data-attachment-id="11209" data-permalink="https://tomaztsql.wordpress.com/2026/08/01/little-useless-useful-r-functions-honest-geographical-location-signposts/image-349/" data-orig-file="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image-1.png" data-orig-size="548,678" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","alt":""}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://i2.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=450&#038;ssl=1" src="https://i2.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=450&#038;ssl=1" alt="" class="wp-image-11209" style="aspect-ratio:0.8082737958054851;width:383px;height:auto" srcset_temp="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image-1.png 548w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=121 121w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=242 242w" sizes="(max-width: 548px) 100vw, 548px" data-recalc-dims="1" /></a></figure>
</div>


<p class="wp-block-paragraph">I have inserted the real values of air distances between Ljubljana all all four cities: Koper, Celje, Maribor, Kranj using <a href="https://www.distancefromto.net/" rel="nofollow" target="_blank">air distance calculator.</a></p>



<p class="wp-block-paragraph">And this where the circles should meet <img src="https://i1.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png?w=578&#038;ssl=1" alt="&#x1f642;" class="wp-smiley" style="height: 1em; max-height: 1em;" data-recalc-dims="1" /></p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><a href="https://i2.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png?ssl=1" rel="nofollow" target="_blank"><img loading="lazy" data-attachment-id="11211" data-permalink="https://tomaztsql.wordpress.com/2026/08/01/little-useless-useful-r-functions-honest-geographical-location-signposts/where_we_meet/" data-orig-file="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png" data-orig-size="1800,1800" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","alt":""}" data-image-title="where_we_meet" data-image-description="" data-image-caption="" data-large-file="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png?w=605" src="https://i2.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png?w=450&#038;ssl=1" alt="" class="wp-image-11211" style="width:623px;height:auto" srcset_temp="https://i2.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png?w=450&#038;ssl=1 1024w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png?w=150 150w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png?w=300 300w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png?w=768 768w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png?w=1440 1440w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png 1800w" sizes="(max-width: 1024px) 100vw, 1024px" data-recalc-dims="1" /></a></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">So if you are enjoying your vacation and you stumble upon a sign, check it and let me know, if it corresponds to your location of not <img src="https://i1.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png?w=578&#038;ssl=1" alt="&#x1f642;" class="wp-smiley" style="height: 1em; max-height: 1em;" data-recalc-dims="1" /></p>



<p class="wp-block-paragraph">As always, the complete code is available on GitHub in  <a href="https://github.com/tomaztk/Useless_R_functions" rel="nofollow" target="_blank">Useless_R_function repository</a>  and the file  Honest_geographical_location_signposts.R is  <a href="https://github.com/tomaztk/Useless_R_functions/blob/main/functions/Honest_geographical_location_signposts.R" rel="nofollow" target="_blank">here</a>.</p>



<p class="wp-block-paragraph">Check the repository for future updates!</p>



<p class="wp-block-paragraph">Stay healthy, hydrated and happy R-coding!</p>

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://tomaztsql.wordpress.com/2026/08/01/little-useless-useful-r-functions-honest-geographical-location-signposts/"> R – TomazTsql</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/little-useless-useful-r-functions-honest-geographical-location-signposts/">Little useless-useful R functions – Honest geographical location signposts</a>]]></content:encoded>
					
		
		<enclosure url="https://2.gravatar.com/avatar/84af3d4db7552aa6f0fc3db37b65871290b5174af7d5b84c3f185ca92ccfb237?s=96&#038;d=identicon&#038;r=G" length="0" type="" />
<enclosure url="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image.png?w=877" length="0" type="" />
<enclosure url="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=548" length="0" type="" />
<enclosure url="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png?w=1024" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402905</post-id>	</item>
		<item>
		<title>&#8216;garchf&#8217;: GARCH probabilistic forecasting with package &#8216;forecast&#8217;-style interface (and &#8216;rugarch&#8217; under the hood)</title>
		<link>https://www.r-bloggers.com/2026/07/garchf-garch-probabilistic-forecasting-with-package-forecast-style-interface-and-rugarch-under-the-hood/</link>
		
		<dc:creator><![CDATA[T. Moudiki]]></dc:creator>
		<pubDate>Sat, 01 Aug 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://thierrymoudiki.github.io//blog/2026/08/01/r/xgarchf</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> The package garchf wraps<br />
the extensive GARCH modeling machinery in<br />
rugarch<br />
behind a<br />
forecast-style<br />
interface, so that GARCH-based forecasts can be produced, plotted, and<br />
evaluated with the same conventions used throughout the forecast<br />
ecosystem (in the...</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/garchf-garch-probabilistic-forecasting-with-package-forecast-style-interface-and-rugarch-under-the-hood/">‘garchf’: GARCH probabilistic forecasting with package ‘forecast’-style interface (and ‘rugarch’ under the hood)</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://thierrymoudiki.github.io//blog/2026/08/01/r/xgarchf"> T. Moudiki's Webpage - R</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<p>The package <a href="https://techtonique.r-universe.dev/garchf" rel="nofollow" target="_blank"><code>garchf</code></a> wraps
the extensive GARCH modeling machinery in
<a href="https://cran.r-project.org/web/packages/rugarch/index.html" rel="nofollow" target="_blank"><code>rugarch</code></a>
behind a
<a href="https://cran.r-project.org/web/packages/forecast/index.html" rel="nofollow" target="_blank"><code>forecast</code></a>-style
interface, so that GARCH-based forecasts can be produced, plotted, and
evaluated with the same conventions used throughout the <code>forecast</code>
ecosystem (in the spirit of functions like <code>forecast::thetaf()</code>). The
workhorse function, <code>xgarchf()</code>, fits a GARCH model to a univariate time
series – with a choice of variance model (<code>sGARCH</code>, <code>eGARCH</code>,
<code>gjrGARCH</code>, <code>apARCH</code>, <code>iGARCH</code>, …), ARMA order for the conditional mean,
GARCH order, and conditional distribution – and returns a standard
<code>forecast</code> object containing point forecasts, prediction intervals, and
simulated paths. Because the output integrates with <code>forecast</code>’s S3
methods, <code>plot()</code> and other generics work out of the box, and the
simulated paths (<code>sims</code>) make it straightforward to compute richer
probabilistic forecasting metrics (CRPS, pinball loss, Winkler scores,
etc.) via cross-validation. Below, we illustrate <code>xgarchf()</code> on Google’s
daily closing stock price returns, and then run a small cross-validation
exercise comparing a few GARCH variants using the
<a href="https://github.com/Techtonique/crossvalidation" rel="nofollow" target="_blank"><code>crossvalidation</code></a>
package.</p>

<pre>library(garchf)

Registered S3 method overwritten by 'quantmod':
  method            from
  as.zoo.data.frame zoo 
</pre>

<h1 id="1---graphs">1 &#8211; Graphs</h1>

<pre>y &lt;- diff(log(fpp2::goog200))

fit1 &lt;- xgarchf(y, h = 20, model = &quot;eGARCH&quot;)
fit2 &lt;- xgarchf(y, h = 20, model = &quot;sGARCH&quot;)
fit3 &lt;- xgarchf(y, h = 20, model = &quot;gjrGARCH&quot;)
fit4 &lt;- xgarchf(y, h = 20, model = &quot;iGARCH&quot;)

print(summary(fitted(fit1)))

    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
0.001504 0.001504 0.001504 0.001504 0.001504 0.001504     
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
0.002783 0.002783 0.002783 0.002783 0.002783 0.002783     
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
0.001233 0.001233 0.001233 0.001233 0.001233 0.001233     
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
0.001485 0.001485 0.001485 0.001485 0.001485 0.001485 
</pre>

<p><img src="https://i0.wp.com/thierrymoudiki.github.io/images/2026-08-01/2026-08-01-xgarchf_3_1.png?w=578&#038;ssl=1" alt="image-title-here" class="img-responsive" data-recalc-dims="1" /></p>

<pre>    Ljung-Box test

data:  Residuals
Q* = 10.341, df = 10, p-value = 0.4111

Model df: 0.   Total lags used: 10
</pre>

<p><img src="https://i1.wp.com/thierrymoudiki.github.io/images/2026-08-01/2026-08-01-xgarchf_3_3.png?w=578&#038;ssl=1" alt="image-title-here" class="img-responsive" data-recalc-dims="1" /></p>

<pre>    Ljung-Box test

data:  Residuals
Q* = 10.341, df = 10, p-value = 0.4111

Model df: 0.   Total lags used: 10
</pre>

<p><img src="https://i2.wp.com/thierrymoudiki.github.io/images/2026-08-01/2026-08-01-xgarchf_3_5.png?w=578&#038;ssl=1" alt="image-title-here" class="img-responsive" data-recalc-dims="1" /></p>

<pre>    Ljung-Box test

data:  Residuals
Q* = 10.341, df = 10, p-value = 0.4111

Model df: 0.   Total lags used: 10
</pre>

<p><img src="https://i1.wp.com/thierrymoudiki.github.io/images/2026-08-01/2026-08-01-xgarchf_3_7.png?w=578&#038;ssl=1" alt="image-title-here" class="img-responsive" data-recalc-dims="1" /></p>

<pre>    Ljung-Box test

data:  Residuals
Q* = 10.341, df = 10, p-value = 0.4111

Model df: 0.   Total lags used: 10
</pre>

<p><img src="https://i2.wp.com/thierrymoudiki.github.io/images/2026-08-01/2026-08-01-xgarchf_3_9.png?w=578&#038;ssl=1" alt="image-title-here" class="img-responsive" data-recalc-dims="1" /></p>

<h1 id="2---cross-validation-with-the-package-crossvalidation">2 - Cross-validation with the package <a href="https://github.com/Techtonique/crossvalidation" rel="nofollow" target="_blank"><code>crossvalidation</code></a></h1>

<p>For <code>crossvalidation</code>, see
<a href="https://github.com/Techtonique/crossvalidation" rel="nofollow" target="_blank">https://github.com/Techtonique/crossvalidation</a>.</p>

<pre>spl_m5 &lt;- function(predicted,
                   observed,
                   probs = c(0.005, 0.025, 0.165, 0.25,
                             0.5,
                             0.75, 0.835, 0.975, 0.995))
{
  if (is.null(predicted$sims)) {
    stop(&quot;predicted$sims is required&quot;)
  }

  # training series from forecast object
  train &lt;- as.numeric(predicted$x)

  # M5 scaling denominator
  scale_denom &lt;- mean(abs(diff(train)), na.rm = TRUE)

  if (scale_denom &lt;= 0 || !is.finite(scale_denom)) {
    scale_denom &lt;- 1
  }

  sims &lt;- predicted$sims

  # quantile forecasts: rows = horizons, cols = probs
  qhat &lt;- sapply(
    probs,
    function(p) apply(sims, 1, stats::quantile, probs = p, na.rm = TRUE)
  )

  observed &lt;- as.numeric(observed)

  # pinball loss
  pinball_vec &lt;- numeric(length(probs))

  for (j in seq_along(probs)) {

    u &lt;- probs[j]
    q &lt;- qhat[, j]

    pinball_vec[j] &lt;- mean(
      ifelse(
        observed &gt;= q,
        u * (observed - q),
        (1 - u) * (q - observed)
      ),
      na.rm = TRUE
    )
  }

  # scaled pinball loss for each quantile
  spl_vec &lt;- pinball_vec / scale_denom

  # average scaled pinball loss
  mean_spl &lt;- mean(spl_vec)

  out &lt;- c(
    mean_SPL = mean_spl
  )

  names(spl_vec) &lt;- paste0(&quot;SPL_&quot;, probs)

  c(out, spl_vec)
}

eval_metric95 &lt;- function(predicted, observed)
{
  error &lt;- observed - predicted$mean

  rmse &lt;- sqrt(mean(error^2))
  mae &lt;- mean(abs(error))

  # Only one interval returned
  lower &lt;- predicted$lower
  upper &lt;- predicted$upper

  coverage &lt;- mean(
    observed &gt;= lower & observed &lt;= upper
  )

  alpha &lt;- 0.05

  winkler &lt;- ifelse(
    observed &lt; lower,
    (upper - lower) + (2 / alpha) * (lower - observed),
    ifelse(
      observed &gt; upper,
      (upper - lower) + (2 / alpha) * (observed - upper),
      (upper - lower)
    )
  )

  spl &lt;- spl_m5(predicted, observed)

  c(
    RMSE = rmse,
    MAE = mae,
    Coverage95 = coverage,
    Winkler95 = mean(winkler),
    CRPS = mean(scoringRules::crps_sample(observed, predicted$sims)),
    mean_SPL = as.numeric(spl[&quot;mean_SPL&quot;])
  )
}

eval_metric80 &lt;- function(predicted, observed)
{
  error &lt;- observed - predicted$mean

  me &lt;- mean(error)
  rmse &lt;- sqrt(mean(error^2))
  mae &lt;- mean(abs(error))

  # Only one interval returned
  lower &lt;- predicted$lower
  upper &lt;- predicted$upper

  coverage &lt;- mean(
    observed &gt;= lower & observed &lt;= upper
  )

  alpha &lt;- 0.2

  winkler &lt;- ifelse(
    observed &lt; lower,
    (upper - lower) + (2 / alpha) * (lower - observed),
    ifelse(
      observed &gt; upper,
      (upper - lower) + (2 / alpha) * (observed - upper),
      (upper - lower)
    )
  )

  spl &lt;- spl_m5(predicted, observed)

  c(
    ME = me,
    RMSE = rmse,
    MAE = mae,
    Coverage80 = coverage,
    Winkler80 = mean(winkler),
    CRPS = mean(scoringRules::crps_sample(observed, predicted$sims)),
    mean_SPL = as.numeric(spl[&quot;mean_SPL&quot;])
  )
}

res &lt;- crossvalidation::crossval_ts(
  y = y,
  initial_window = 150,
  horizon = 10,
  fixed_window = FALSE,
  fcast_func = garchf::xgarchf,
  eval_metric = eval_metric95,
  fit_params = list(arma_order=c(0, 0), 
                    garch_order = c(1, 1),
                    model = &quot;eGARCH&quot;,
                    level=95),
  show_progress = FALSE
)
print(summary(res))

res &lt;- crossvalidation::crossval_ts(
  y = y,
  initial_window = 150,
  horizon = 10,
  fixed_window = FALSE,
  fcast_func = garchf::xgarchf,
  eval_metric = eval_metric95,
  fit_params = list(arma_order=c(0, 0), 
                    garch_order = c(1, 1),
                    model = &quot;sGARCH&quot;,
                    level=95),
  show_progress = FALSE
)
print(summary(res))

res &lt;- crossvalidation::crossval_ts(
  y = y,
  initial_window = 150,
  horizon = 10,
  fixed_window = FALSE,
  fcast_func = garchf::xgarchf,
  eval_metric = eval_metric95,
  fit_params = list(arma_order=c(0, 0), 
                    garch_order = c(1, 1),
                    model = &quot;iGARCH&quot;,
                    level=95),
  show_progress = FALSE
)
print(summary(res))

      RMSE               MAE             Coverage95       Winkler95      
 Min.   :0.006459   Min.   :0.004896   Min.   :0.7000   Min.   :0.03441  
 1st Qu.:0.008001   1st Qu.:0.006266   1st Qu.:0.9000   1st Qu.:0.06153  
 Median :0.009135   Median :0.007061   Median :1.0000   Median :0.06466  
 Mean   :0.017189   Mean   :0.010613   Mean   :0.9475   Mean   :0.20090  
 3rd Qu.:0.022415   3rd Qu.:0.015066   3rd Qu.:1.0000   3rd Qu.:0.47706  
 Max.   :0.042741   Max.   :0.023054   Max.   :1.0000   Max.   :0.96625  
      CRPS             mean_SPL     
 Min.   :0.004154   Min.   :0.1170  
 1st Qu.:0.004922   1st Qu.:0.1362  
 Median :0.005311   Median :0.1481  
 Mean   :0.010039   Mean   :0.3380  
 3rd Qu.:0.017800   3rd Qu.:0.6763  
 Max.   :0.051416   Max.   :1.6607        

      RMSE               MAE             Coverage95       Winkler95      
 Min.   :0.006554   Min.   :0.005380   Min.   :0.7000   Min.   :0.03856  
 1st Qu.:0.008424   1st Qu.:0.006561   1st Qu.:0.9750   1st Qu.:0.06261  
 Median :0.009314   Median :0.007401   Median :1.0000   Median :0.07277  
 Mean   :0.017155   Mean   :0.010741   Mean   :0.9525   Mean   :0.17716  
 3rd Qu.:0.020081   3rd Qu.:0.013012   3rd Qu.:1.0000   3rd Qu.:0.34988  
 Max.   :0.042568   Max.   :0.022999   Max.   :1.0000   Max.   :0.49756  
      CRPS             mean_SPL     
 Min.   :0.004634   Min.   :0.1349  
 1st Qu.:0.005383   1st Qu.:0.1516  
 Median :0.005695   Median :0.1606  
 Mean   :0.008842   Mean   :0.2986  
 3rd Qu.:0.012903   3rd Qu.:0.4725  
 Max.   :0.019442   Max.   :0.7436        

    RMSE               MAE             Coverage95       Winkler95      
 Min.   :0.006556   Min.   :0.005514   Min.   :0.7000   Min.   :0.03580  
 1st Qu.:0.008306   1st Qu.:0.006239   1st Qu.:0.9750   1st Qu.:0.06307  
 Median :0.009119   Median :0.007007   Median :1.0000   Median :0.06478  
 Mean   :0.017029   Mean   :0.010484   Mean   :0.9525   Mean   :0.16725  
 3rd Qu.:0.018881   3rd Qu.:0.011711   3rd Qu.:1.0000   3rd Qu.:0.16760  
 Max.   :0.042713   Max.   :0.023064   Max.   :1.0000   Max.   :0.51546  
      CRPS             mean_SPL     
 Min.   :0.004851   Min.   :0.1363  
 1st Qu.:0.005317   1st Qu.:0.1510  
 Median :0.005700   Median :0.1591  
 Mean   :0.008720   Mean   :0.2928  
 3rd Qu.:0.009316   3rd Qu.:0.3126  
 Max.   :0.019649   Max.   :0.7586  
</pre>

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://thierrymoudiki.github.io//blog/2026/08/01/r/xgarchf"> T. Moudiki's Webpage - R</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/garchf-garch-probabilistic-forecasting-with-package-forecast-style-interface-and-rugarch-under-the-hood/">‘garchf’: GARCH probabilistic forecasting with package ‘forecast’-style interface (and ‘rugarch’ under the hood)</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402913</post-id>	</item>
		<item>
		<title>Evaluating LLMs/AI for Media Planning in R</title>
		<link>https://www.r-bloggers.com/2026/07/evaluating-llms-ai-for-media-planning-in-r/</link>
		
		<dc:creator><![CDATA[Florian Teschner]]></dc:creator>
		<pubDate>Sat, 01 Aug 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">http://flovv.github.io/llm-media-evals-in-r/</guid>

					<description><![CDATA[<p>LLMs can produce a convincing media recommendation in a few seconds. The more useful question is whether the recommendation is correct: are the reach calculations right, are the assumptions visible, and does the plan fit the brief?</p>
<p>I work at Havas Med...</p>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/evaluating-llms-ai-for-media-planning-in-r/">Evaluating LLMs/AI for Media Planning in R</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="http://flovv.github.io/llm-media-evals-in-r/"> Florian Teschner</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<p>LLMs can produce a convincing media recommendation in a few seconds. The more useful question is whether the recommendation is correct: are the reach calculations right, are the assumptions visible, and does the plan fit the brief?</p>

<p>I work at Havas Media and I am the author of the <a href="https://havasmedia.de/hqai/#benchmark" rel="nofollow" target="_blank">Havas AI Media Quality Index (HAI-Q)</a>, a benchmark for media planning in the German market. I built it because generic knowledge tests are not enough for professional AI applications. A model can write a plausible paragraph about media strategy and still get a budget allocation, a target group definition, or a GRP calculation wrong.</p>

<p>This post has three parts. First, I will build a small media-planning evaluation in R using the <a href="https://vitals.tidyverse.org/" rel="nofollow" target="_blank">vitals package</a>. Then I will discuss why media-planning questions are unusually difficult to evaluate. Finally, I will focus on what the HAI-Q results tell us about general-purpose LLMs.</p>

<h2 id="1-a-small-eval-in-r">1. A small eval in R</h2>

<p>At its simplest, an LLM eval has three components:</p>

<ol>
  <li>A dataset containing questions and targets.</li>
  <li>A solver that answers the questions.</li>
  <li>A scorer that evaluates the answers.</li>
</ol>

<p>This is the basic structure used by <a href="https://vitals.tidyverse.org/articles/vitals.html" rel="nofollow" target="_blank">vitals</a>. The <code>target</code> column does not always need to contain one exact answer. For open-ended questions, it can contain grading guidance: what a good answer must include, which assumptions must be stated, and which errors should lose credit.</p>

<p>This is useful for testing the final answer of an LLM. It is less useful as a complete test of an AI agent. An agent consists of a harness and one or more models: it may retrieve data, call tools, run calculations, retry a failed step, maintain state, and decide when to ask for help. <code>vitals</code> mainly gives us a dataset, a solver, and a scorer. It does not automatically tell us whether the agent used the right tool, passed the right arguments, or recovered safely from an intermediate failure. It can be extended with custom solvers, but then the agent harness and trajectory checks still have to be built separately.</p>

<h3 id="the-questions">The questions</h3>

<p>Here is a deliberately small evaluation set. The questions cover calculation, planning, and interpretation. The targets are written as instructions for a grader rather than as model answers.</p>

<figure class="highlight"><pre>library(dplyr)
library(tibble)

media_questions &lt;- tribble(
  ~id, ~input, ~target, ~domain, ~task,

  &quot;grp-calculation&quot;,
  &quot;A campaign delivers 60% reach at an average frequency of 3. What is the campaign's GRP? State the assumption behind the calculation.&quot;,
  &quot;A full-credit answer calculates 60 * 3 = 180 GRP. It explains that this is the standard simplified relationship GRP = reach (in percent) * average frequency. It must not describe GRP as the number of unique people reached.&quot;,
  &quot;Reach and GRP&quot;, &quot;Calculation&quot;,

  &quot;budget-allocation&quot;,
  &quot;A client has EUR 100,000 to reach adults aged 25-49 in Germany. There is no historical channel performance data. Propose a first-pass media allocation and explain how you would improve it after launch.&quot;,
  &quot;There is no single correct allocation. A strong answer makes the uncertainty explicit, explains the role of each channel, avoids inventing CPMs or reach figures, and proposes a measurement and test-and-learn plan. It should distinguish a planning hypothesis from an observed result.&quot;,
  &quot;Media strategy&quot;, &quot;Recommendation&quot;,

  &quot;reach-frequency-tradeoff&quot;,
  &quot;Two plans have the same budget. Plan A has higher reach and lower frequency; Plan B has lower reach and higher frequency. How would you decide between them?&quot;,
  &quot;A full-credit answer says that the choice depends on the communication objective, the selected channesls, the overall attention, audience size, purchase cycle, creative strength, and expected response. It should explain the reach-frequency trade-off and ask for missing information instead of declaring one plan universally better.&quot;,
  &quot;Media strategy&quot;, &quot;Reasoning&quot;
)

media_questions</pre></figure>

<p>The questions are intentionally specific. “Create a good media plan” is difficult to score because almost any fluent answer can sound reasonable. A question about GRP, in contrast, gives us a concrete numerical check. The budget question tests something different: whether the model knows when it does not have enough information to justify a precise allocation.</p>

<p>In a real eval, I would expand this table with questions about channel roles, target-group definitions, reach curves, media costs, campaign objectives, and German market data. I would also add metadata such as difficulty, source, market, and the date on which the underlying data was valid.</p>

<h3 id="the-solver-and-scorer">The solver and scorer</h3>

<p>The <a href="https://vitals.tidyverse.org/articles/vitals.html" rel="nofollow" target="_blank">vitals introduction</a> uses <code>Task$new()</code> to combine the dataset, a solver, and a scorer. The following example uses Claude as the solver and an LLM-based grader. An API key for the selected provider is required.</p>

<figure class="highlight"><pre>library(vitals)
library(ellmer)

media_task &lt;- Task$new(
  dataset = media_questions,
  solver = generate(
    chat_openrouter(model = &quot;claude-sonnet-4.6&quot;)
  ),
  scorer = model_graded_qa(partial_credit = TRUE),
  name = &quot;A small media-planning eval&quot;
)

# Run the solver and scorer.
media_task$eval()

# Bind the results into a tibble for analysis.
media_scores &lt;- vitals_bind(media_task)
media_scores

media_scores |&gt;
  count(score)</pre></figure>

<p>With <code>partial_credit = TRUE</code>, the scorer can return <code>C</code> for correct, <code>P</code> for partially correct, or <code>I</code> for incorrect. This is more useful than a single binary score for media planning. A response may use the right calculation but fail to explain its assumptions. Another answer may be directionally useful but invent a media cost. Those are different failures and should not be hidden in one number.</p>

<p>The result is not the end of the evaluation. I would inspect the individual answers and the grading decisions, especially on the first few runs. If the grader repeatedly gives full credit to a response that I consider unsafe, the problem may be the grading guidance rather than the model.</p>

<h3 id="comparing-models">Comparing models</h3>

<p>Once the task exists, comparing solvers is straightforward. For example, the same questions can be evaluated with an OpenAI model and then combined with the first run.</p>

<figure class="highlight"><pre>media_task_openai &lt;- media_task$clone()

media_task_openai$eval(
  solver_chat = chat_openrouter(model = &quot;gpt-5.4&quot;)
)

comparison &lt;- vitals_bind(
  claude = media_task,
  openai = media_task_openai
) |&gt;
  mutate(model = recode(
    task,
    claude = &quot;Claude&quot;,
    openai = &quot;OpenAI&quot;
  ))

comparison |&gt;
  count(model, score)</pre></figure>

<p>The exact model names will change over time. The important part is to keep the questions and scoring rules stable while changing one component at a time. Otherwise, a score difference is difficult to interpret.</p>

<p>This example is an LLM eval, not an agent eval. It compares the text returned at the end of the solver. For an agent, I would additionally log the tool calls, retrieved documents, intermediate calculations, retries, latency, cost, and final answer. The test should then assert properties of the whole trajectory, not only the final prose.</p>

<h2 id="2-why-media-planning-evals-are-hard">2. Why media-planning evals are hard</h2>

<p>Media planning looks like a natural use case for LLMs. The work involves briefs, audience descriptions, channel recommendations, calculations, and written rationales. But the same combination makes the evaluation difficult.</p>

<h3 id="there-is-rarely-one-correct-plan">There is rarely one correct plan</h3>

<p>Many planning questions are underdetermined. A sensible allocation depends on the objective, budget, campaign length, audience size, creative assets, buying conditions, historical performance, and measurement setup. Two experienced planners can recommend different channel mixes and both be right.</p>

<p>This means that a target should often describe required properties rather than prescribe one number. For example, a full-credit answer might need to:</p>

<ul>
  <li>state its assumptions;</li>
  <li>stay within the budget;</li>
  <li>connect channel choices to the objective;</li>
  <li>distinguish facts from hypotheses; and</li>
  <li>explain how the plan would be measured and revised.</li>
</ul>

<p>The evaluator has to reward sound reasoning without turning one planner’s preference into a false ground truth.</p>

<h3 id="media-facts-are-local-and-time-dependent">Media facts are local and time-dependent</h3>

<p>A media answer can be correct in one market and wrong in another. Reach, costs, inventory, audience definitions, platform availability, and panel methodology all vary by country and by date. A model that has learned general media vocabulary does not automatically have access to the latest German market data.</p>

<p>This is why a useful eval should record the market and the data vintage. It should also test whether the model provides a source or clearly labels an assumption when a current figure is unavailable. “The average CPM is X” is not a safe answer if the model cannot explain where X came from.</p>

<h3 id="definitions-matter-more-than-fluent-prose">Definitions matter more than fluent prose</h3>

<p>Media planning has many terms that are close enough to sound interchangeable but are not interchangeable in a calculation. Reach can mean gross or net reach. Frequency can be average or effective frequency. GRP is not the same as the number of unique people reached. Target-group percentages need a denominator.</p>

<p>These distinctions create easy failure modes. A response can contain the right formula but apply it to the wrong quantity. It can also produce a tidy table whose totals do not add up. Numerical checks and constraint checks therefore need to be part of the eval, not just a general assessment of writing quality.</p>

<h3 id="llm-as-a-judge-is-useful-but-not-sufficient">LLM-as-a-judge is useful but not sufficient</h3>

<p>The <code>model_graded_qa()</code> scorer in <code>vitals</code> makes open-ended evaluation scalable. It is also a model judging another model’s answer, which introduces its own errors. A grader may prefer confident language, overlook a subtle numerical mistake, or accept an answer because it resembles the supplied guidance.</p>

<p>For a serious benchmark, I would calibrate the grader against human-labelled examples and keep a sample for manual review. I would also separate different dimensions where possible:</p>

<ul>
  <li>factual accuracy;</li>
  <li>numerical accuracy;</li>
  <li>constraint satisfaction;</li>
  <li>quality of reasoning; and</li>
  <li>usefulness of the recommendation.</li>
</ul>

<p>One overall score is convenient, but it can hide which part of the planning process is failing.</p>

<h3 id="vitals-is-not-an-agent-harness"><code>vitals</code> is not an agent harness</h3>

<p>The distinction matters in practice. <code>vitals</code> is a useful way to ask an LLM a fixed set of questions and score the answers. It is not, by itself, a test harness for an AI agent. If an agent has access to a reach database, a calculator, or a planning API, the evaluation needs to check the interaction with those components as well.</p>

<p>For an end-to-end agent eval, I would test at least four layers: whether the harness selects the right tool, whether the tool call is valid, whether the intermediate result is interpreted correctly, and whether the final answer communicates uncertainty. A final response can look reasonable even when one of those earlier steps failed.</p>

<h2 id="3-results-from-the-havas-hai-q">3. Results from the Havas HAI-Q</h2>

<p>The <a href="https://havasmedia.de/hqai/#benchmark" rel="nofollow" target="_blank">Havas HAI-Q page</a> describes a benchmark built for media planning in the German market. It contains 35 practical tasks across five areas:</p>

<ol>
  <li>Media strategy</li>
  <li>Channel and budget allocation</li>
  <li>Target-group evaluation</li>
  <li>Reach and GRP</li>
  <li>Media and effectiveness metrics</li>
</ol>

<p>In this post I focus on the general-purpose LLM results:</p>

<table>
  <thead>
    <tr>
      <th>Model</th>
      <th style="text-align: right">Correct answers</th>
      <th style="text-align: right">Share correct</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>GPT-5</td>
      <td style="text-align: right">16 / 35</td>
      <td style="text-align: right">45.7%</td>
    </tr>
    <tr>
      <td>Claude Sonnet 4.5</td>
      <td style="text-align: right">6 / 35</td>
      <td style="text-align: right">17.1%</td>
    </tr>
    <tr>
      <td>GPT-4o</td>
      <td style="text-align: right">4 / 35</td>
      <td style="text-align: right">11.4%</td>
    </tr>
  </tbody>
</table>

<p>The headline is uncomfortable: even GPT-5, the strongest general-purpose model in this comparison, is correct on fewer than half of the questions. It answers 16 of 35 questions correctly, leaving 19 answers that are not counted as correct. For practical media-planning work, that is not a safe error rate.</p>

<p>When I look at the individual HAI-Q questions, the errors are not evenly distributed. The models particularly struggle with numeric questions involving reach figures and audience sizes. They can produce a fluent explanation of a planning idea and still make a basic mistake in a denominator, a percentage, or the interpretation of a reach number. This is exactly the type of failure that is easy to miss if evaluation is based on plausibility rather than calculation.</p>

<p>There is also a clear improvement between the older and newer models. GPT-4o answers 4 of 35 questions correctly, compared with 16 of 35 for GPT-5. That is 12 additional correct answers and an improvement from 11.4% to 45.7%, or 34.3 percentage points. GPT-5 gets four times as many questions correct as GPT-4o on this benchmark. The improvement is substantial, even though the newer model is still not reliable enough for unsupervised media decisions.</p>

<p>Claude Sonnet 4.5 scores lower in this test, with 6 of 35 correct answers. This does not mean that the model is generally poor. It means that a general language benchmark and a domain-specific media-planning benchmark answer different questions. The HAI-Q is designed around the German market and a specific definition of correctness, including the numerical details that matter in planning.</p>

<p>The aggregate scores should still be read with care. They do not show the difficulty of every question, the variance across repeated runs, or the exact scoring decision for every answer. But the pattern is clear enough to be useful: current general-purpose LLMs are good at sounding like media planners, while still struggling to answer roughly half of these practical questions correctly.</p>

<h2 id="takeaways">Takeaways</h2>

<p>An LLM eval for media planning should start with real questions from the workflow, not generic prompts about marketing. In R, a tibble with <code>input</code> and <code>target</code> is enough to get started, and <code>vitals</code> provides a practical way to connect questions, solvers, scorers, and result inspection.</p>

<p>The difficult part is not running the model. It is defining what “correct” means when several plans can be reasonable, data changes by market and date, and a plausible answer can contain a subtle but consequential error. For agents, the evaluation also needs to cover the harness, tools, intermediate steps, and failure handling. A final answer score is not enough.</p>

<p>The HAI-Q results show that the latest general-purpose LLMs still answer more than half of these media-planning questions incorrectly. The largest weaknesses appear in numerical reasoning around reach and audience sizes. At the same time, the jump from GPT-4o to GPT-5 shows that model development is moving in the right direction.</p>

<p>For me, the practical conclusion is simple: use LLMs to accelerate media work, but test every numerical recommendation before relying on it. The next step is to combine model evals such as HAI-Q with end-to-end agent tests that measure tool use and the full planning workflow.</p>

<h3 id="resources">Resources</h3>

<ul>
  <li><a href="https://vitals.tidyverse.org/articles/vitals.html" rel="nofollow" target="_blank">Getting started with vitals</a></li>
  <li><a href="https://vitals.tidyverse.org/" rel="nofollow" target="_blank">vitals documentation</a></li>
  <li><a href="https://havasmedia.de/hqai/#benchmark" rel="nofollow" target="_blank">HAI-Q: Havas AI Media Quality Index</a></li>
  <li><a href="https://ellmer.tidyverse.org/" rel="nofollow" target="_blank">ellmer documentation</a></li>
</ul>

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://flovv.github.io/llm-media-evals-in-r/"> Florian Teschner</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/evaluating-llms-ai-for-media-planning-in-r/">Evaluating LLMs/AI for Media Planning in R</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402903</post-id>	</item>
		<item>
		<title>US oil stocks by @ellis2013nz</title>
		<link>https://www.r-bloggers.com/2026/07/us-oil-stocks-by-ellis2013nz/</link>
		
		<dc:creator><![CDATA[free range statistics - R]]></dc:creator>
		<pubDate>Fri, 31 Jul 2026 13:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://freerangestats.info/blog/2026/08/01/fuel-crisis</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> Like many people I have been keeping track of the slow-burn fuel crisis arising from the war in Iran, its possible expansion to the Red Sea, and exacerbation from the ongoing war between Russia and Ukraine. The latter seems to have reached a stage wher...</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/us-oil-stocks-by-ellis2013nz/">US oil stocks by @ellis2013nz</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://freerangestats.info/blog/2026/08/01/fuel-crisis"> free range statistics - R</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<p>Like many people I have been keeping track of the slow-burn fuel crisis arising from the war in Iran, its possible expansion to the Red Sea, and exacerbation from the ongoing war between Russia and Ukraine. The latter seems to have reached a stage where serious damage is being done to Russia’s refining capacity and petro products’ exports.</p>

<p>I’ve now started a page on this website with <a href="https://freerangestats.info/fuel-crisis/index.html" rel="nofollow" target="_blank">a few charts on the fuel crisis</a> that I’m going to be keeping up to date.</p>

<h2 id="stocks-of-crude-are-going-down-but-how-much-is-left">Stocks of crude are going down, but “how much is left”?</h2>

<p>The motivation for today’s post was that I’d been seeing many news and opinion articles about how the US crude oil stocks—in total, and in the Strategic Petroleum Reserve in particular—have declined to modern record lows. But expert commentators are reluctant to show this decline in relation to the absolute amount left, as opposed to comparisons to seasonal or historic lows. This is understandable because no-one really knows (or perhaps tells) what the real “tank bottoms” are in a big complex system like the USA. A certain amount of oil, of uncertain volume but certainly in the tens (and possibly hundreds) of millions of barrels, is needed just to keep various bits of plumbing or storage from seizing up or collapsing.</p>

<p>So it’s hard to get a chart like this one, and I had to make it myself:</p>

<object type="image/svg+xml" data="https://freerangestats.info/img/0327-us-crude-from2000-01-01.svg" width="450"><img src="https://i2.wp.com/freerangestats.info/img/0327-us-crude-from2000-01-01.png?w=450&#038;ssl=1" data-recalc-dims="1" /></object>

<p>I’ve got no reputation as an oil expert to worry about, so I can safely draw those lines at a fairly arbitrary 24 (or 30) days of refinery throughput, and calculate the time it will take to get to those low levels “at the current rate”. It’s simplistic, but it’s an important reality check to see that there might be about 19 weeks left.</p>

<p>Fast as the stocks are being used up, the USA has a <em>lot</em> of oil available to it. But 19 weeks isn’t that many. Markets are betting that good things will happen in the weeks or months before the blue line reaches the red line. Because of that, oil is currently selling for around $90 per barrel instead of the $110+ that would be justified if people thought we had lost the traffic through the Strait of Hormuz indefinitely.</p>

<p>Not that I think 19 weeks is a realistic forecast. Long before US stocks reached that red line, there would be economic and political chaos. Efforts to keep retail prices artificially low would probably be overwhelmed and there would be material demand destruction. There would also be huge incentives for the US to give away anything to restore Persian Gulf and Red Sea transit routes. 19 weeks gives us a time frame within which <em>something</em> will have to change.</p>

<p>The value-add for me from this chart is showing the total oil available for the US in the event this becomes a real emergency for them; the comparison of that to a meaningful if arbitrary threshold in terms of days of refinery cover; and the calculation of weeks left at current draw-down rates to reach that high stress threshold.</p>

<h2 id="break-out-the-spr-and-also-look-at-gasoline-distillates">Break out the SPR and also look at gasoline, distillates</h2>

<p>The same data source has a lot of other detailed information, most of it far too detailed for me, but I’m interested enough in four key headline variables that are more detailed than “total stocks of crude oil”. In this chart I break down the total stocks into those in the Strategic Petroleum Reserve, and those in more normally accessed stocks. I also show the amounts held of two key refined products:</p>

<object type="image/svg+xml" data="https://freerangestats.info/img/0327-facet-us-stocks.svg" width="450"><img src="https://i1.wp.com/freerangestats.info/img/0327-facet-us-stocks.png?w=450&#038;ssl=1" data-recalc-dims="1" /></object>

<h2 id="code">Code</h2>

<p>Here’s the code that grabs the data from the US Energy Information Administration and draws that second plot:</p>

<figure class="highlight"><pre>library(tidyverse)
library(readxl)
library(scales)
library(glue)

fn &lt;- &quot;us-petrol-status-weekly.xls&quot;

download.file(
  &quot;https://ir.eia.gov/wpsr/psw01.xls&quot;,
  fn,
  mode = &quot;wb&quot;
)

us_stocks &lt;- read_excel(fn, sheet = &quot;Data 1&quot;, skip = 2) |&gt;
  rename(
    crude = `Weekly U.S. Ending Stocks of Crude Oil  (Thousand Barrels)`,
    crude_spr = `Weekly U.S. Ending Stocks of Crude Oil in SPR  (Thousand Barrels)`,
    gasoline = `Weekly U.S. Ending Stocks of Total Gasoline  (Thousand Barrels)`,
    diesel = `Weekly U.S. Ending Stocks of Distillate Fuel Oil  (Thousand Barrels)`,
    date = Date
  )

#------------------plotting------------------

eia_caption &lt;- glue(&quot;Source: Energy Information Administration (EIA). Accessed {format(Sys.Date(), '%d %B %Y')}&quot;)

# an annotation rectangle we can use in multiple charts
war_rect &lt;- annotate(
  &quot;rect&quot;,
  xmin = as.Date(&quot;2026-02-28&quot;),
  xmax = Inf,
  ymin = -Inf,
  ymax = Inf,
  alpha = 0.5,
  fill = &quot;grey80&quot;
)

# Facet plot of total crude, SPR crude, diesel and gasoline stocks
us_stocks |&gt;
  mutate(com_crude = crude - crude_spr) |&gt;
  select(
    date,
    `Non-SPR crude oil` = com_crude,
    `Crude oil in SPR` = crude_spr,
    `Gasoline` = gasoline,
    `Distillate (mostly diesel)` = diesel
  ) |&gt;
  gather(variable, value, -date) |&gt;
  mutate(variable = fct_reorder(variable, value)) |&gt;
  ggplot(aes(x = date, y = value / 1000)) +
  war_rect +
  facet_wrap(~variable, scales = &quot;free_y&quot;) +
  geom_line(colour = &quot;blue&quot;) +
  expand_limits(y = 0) +
  scale_y_continuous(label = comma) +
  labs(
    x = &quot;&quot;,
    y = &quot;Thousands of barrels&quot;,
    title = &quot;US stocks of crude oil, gasoline, and distillate fuel oil (effectively diesel)&quot;,
    subtitle = &quot;Showing both total crude oil stocks (crude) and those in the Strategic Petroleum Reserve (crude_spr)&quot;,
    caption = eia_caption
  )</pre></figure>

<p>As I side point, I’ve started using <a href="https://tidyverse.org/blog/2025/02/air/" rel="nofollow" target="_blank"><code>air</code></a> to format my code. Nearly always it comes out looking better and easier to read than my manual formatting, and it’s certainly more consistent. Thanks to D. Vaughan and L. Henry and the tidyverse.org project.</p>

<p>And here’s the code to draw my highly polished main plot, the one of total crude oil stocks with the annotations. I’ve tried to do this in a way that it will keep working in the months ahead with minimal maintenance, we’ll see how that goes.</p>

<figure class="highlight"><pre>refinery_throughput &lt;- 17.3 # as at 24 July, operating at 97% of US capacity. Daily refinery use.
plausible_stress &lt;- 30 * refinery_throughput
plausible_high_stress &lt;- 24 * refinery_throughput

crude_growth_summary &lt;- us_stocks |&gt;
  summarise(
    latest_crude = crude[date == max(date)],
    weeks = as.numeric(as.Date(max(date)) - as.Date(&quot;2026-04-03&quot;)) / 7,
    difference = (latest_crude -
      crude[date == as.Date(&quot;2026-04-03&quot;)]) /
      1000,
    ratio = latest_crude / crude[date == as.Date(&quot;2026-04-03&quot;)],
    # growth/decline per week in million barrels e.g. 10m barrels per week:
    difference_rate = difference / weeks,
    # growth/declien rate per week:
    growth_rate = 1 - exp(log(ratio) / weeks)
  ) |&gt;
  mutate(
    weeks_at_this_rate = (plausible_stress - latest_crude / 1000) /
      difference_rate
  )

plot_us_stocks &lt;- function(min_date = &quot;2020-01-01&quot;, lab_x_diff = NULL) {
  if (!&quot;Date&quot; %in% class(min_date)) {
    min_date &lt;- as.Date(min_date)
  }

  if (is.null(lab_x_diff)) {
    days_shown &lt;- as.numeric(as.Date(max(us_stocks$date))) -
      as.numeric(min_date)
    lab_x_diff &lt;- days_shown / 50
  }

  lv &lt;- tail(us_stocks, 1)$crude / 1000

  p2 &lt;- us_stocks |&gt;
    filter(date &gt;= min_date) |&gt;
    ggplot(aes(x = date, y = crude / 1000)) +
    war_rect +
    geom_hline(yintercept = plausible_stress, colour = &quot;darkred&quot;) +
    geom_hline(yintercept = plausible_high_stress, colour = &quot;red&quot;) +
    annotate(
      &quot;text&quot;,
      x = min_date + lab_x_diff,
      y = plausible_stress + 50,
      label = &quot;Illustrative stress threshold:\n30 days of refinery cover&quot;,
      colour = &quot;darkred&quot;,
      hjust = 0
    ) +
    annotate(
      &quot;text&quot;,
      x = min_date + lab_x_diff,
      y = plausible_high_stress - 30,
      label = &quot;Illustrative high stress threshold:\n24 days of refinery cover&quot;,
      colour = &quot;red&quot;,
      hjust = 0,
      vjust = 1
    ) +
    annotate(
      &quot;text&quot;,
      x = max(us_stocks$date) - 5e6,
      y = lv,
      label = glue(
        &quot;{round(lv)} million barrels;\n{round(lv / refinery_throughput)} days of cover&quot;
      ),
      size = 2.9,
      hjust = 1,
      vjust = 1,
      colour = &quot;blue&quot;
    ) +
    geom_line(colour = &quot;blue&quot;) +
    expand_limits(y = 0) +
    scale_y_continuous(
      label = comma,
      sec.axis = sec_axis(
        ~ . / refinery_throughput,
        name = &quot;Days of refinery throughput&quot;
      )
    ) +
    labs(
      x = &quot;&quot;,
      y = &quot;Millions of barrels&quot;,
      title = &quot;U.S. Total Crude Oil Stocks, including Strategic Petroleum Reserve&quot;,
      subtitle = glue(
        &quot;Comparison of existing inventories with refinery throughput as at July 2026.
Decline since peak on 3 April 2026 is at {abs(round(crude_growth_summary$difference_rate, 1))} million barrels per week; {round(crude_growth_summary$weeks_at_this_rate)} weeks from stress threshold at this (hypothetical and linear) rate.&quot;
      ),
      caption = eia_caption
    ) +
    theme(axis.line.y = element_line(colour = &quot;grey50&quot;))

    svglite(
      glue(&quot;all-us-crude-from{min_date}.svg&quot;),
      width = 10,
      height = 7
    )
    print(p2)
    dev.off()
}

plot_us_stocks(&quot;2000-01-01&quot;)
plot_us_stocks(&quot;2020-01-01&quot;)
plot_us_stocks(&quot;2025-01-01&quot;)</pre></figure>

<p>Because I did this plot in the form of a function, I have a couple of variants of the plot. One starting in 2020:</p>

<object type="image/svg+xml" data="https://freerangestats.info/img/0327-us-crude-from2020-01-01.svg" width="450"><img src="https://i2.wp.com/freerangestats.info/img/0327-us-crude-from2020-01-01.png?w=450&#038;ssl=1" data-recalc-dims="1" /></object>

<p>And the other zoomed right in to just January 2025 and onwards:</p>
<object type="image/svg+xml" data="https://freerangestats.info/img/0327-us-crude-from2025-01-01.svg" width="450"><img src="https://i0.wp.com/freerangestats.info/img/0327-us-crude-from2025-01-01.png?w=450&#038;ssl=1" data-recalc-dims="1" /></object>

<p>On the whole I prefer the plot I started with, showing the situation from 2000 and onwards. I’m trying to get some big picture perspective after all.</p>

<p>That’s all for today. The images on this page will stay the same as at the time of writing; but those on <a href="https://freerangestats.info/fuel-crisis/index.html" rel="nofollow" target="_blank">the fuel crisis monitoring page</a> will be updated each week.</p>


<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://freerangestats.info/blog/2026/08/01/fuel-crisis"> free range statistics - R</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/us-oil-stocks-by-ellis2013nz/">US oil stocks by @ellis2013nz</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402911</post-id>	</item>
		<item>
		<title>era 0.6.0: chronological comparison and difference</title>
		<link>https://www.r-bloggers.com/2026/07/era-0-6-0-chronological-comparison-and-difference/</link>
		
		<dc:creator><![CDATA[Joe Roe]]></dc:creator>
		<pubDate>Thu, 30 Jul 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://joeroe.io/2026/07/30/era-0.6.0</guid>

					<description><![CDATA[<p>era v0.6.0 is now available on CRAN:</p>
<p>install.packages("era")<br />
library(era)</p>
<p>This minor release adds functions for chronological comparison of year vectors:</p>
<p>x  # BCE years &#038;lt...</p>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/era-0-6-0-chronological-comparison-and-difference/">era 0.6.0: chronological comparison and difference</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://joeroe.io/2026/07/30/era-0.6.0.html"> Joe Roe</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<p><strong><a href="https://era.joeroe.io/" rel="nofollow" target="_blank">era</a></strong> v0.6.0 is now available <a href="https://cran.r-project.org/package=era" rel="nofollow" target="_blank">on CRAN</a>:</p>

<span id="more-402881"></span>

<pre>install.packages(&quot;era&quot;)
library(era)
</pre>

<p>This minor release adds functions for <a href="https://era.joeroe.io/reference/yr_earlier_than.html" rel="nofollow" target="_blank">chronological comparison</a> of year vectors:</p>

<pre>x &lt;- yr(c(200, 100, 300), &quot;BCE&quot;)
yr_earlier_than(x, yr(150, &quot;BCE&quot;))
#&gt; # BCE years &lt;yr_lgl[3]&gt;:
#&gt; [1] FALSE FALSE  TRUE
#&gt; # Era: Before Common Era (BCE): Gregorian years (365.2425 days), counted backwards from 1

yr_later_than(x, yr(150, &quot;BCE&quot;))
#&gt; # BCE years &lt;yr_lgl[3]&gt;:
#&gt; [1]  TRUE FALSE FALSE
#&gt; # Era: Before Common Era (BCE): Gregorian years (365.2425 days), counted backwards from 1
</pre>

<p>And for <a href="https://era.joeroe.io/reference/yr_difference.html" rel="nofollow" target="_blank">calculating chronological differences</a> between year vectors:</p>

<pre>yr_difference(yr(300, &quot;BCE&quot;), yr(100, &quot;BCE&quot;))
#&gt; # years &lt;yr[1]&gt;:
#&gt; [1] 200
#&gt; # Era: Gregorian years (365.2425 days)
</pre>

<p>These functions are aware of era directionality: “BCE” years count backwards, so 300 BCE is earlier than 100 BCE. They support work on <a href="https://tempo.joeroe.io/" rel="nofollow" target="_blank">tempo</a>, a new package I am working on that represents chronological intervals and the temporal relations between them.</p>

<h2 id="links">Links</h2>

<ul>
  <li><a href="https://cran.r-project.org/package=era" rel="nofollow" target="_blank">era on CRAN</a></li>
  <li><a href="https://era.joeroe.io/" rel="nofollow" target="_blank">era package documentation</a></li>
  <li><a href="https://era.joeroe.io/articles/era.html" rel="nofollow" target="_blank">Introductory vignette</a></li>
  <li><a href="https://github.com/joeroe/era" rel="nofollow" target="_blank">Source code</a> (GitHub)</li>
</ul>
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://joeroe.io/2026/07/30/era-0.6.0.html"> Joe Roe</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/era-0-6-0-chronological-comparison-and-difference/">era 0.6.0: chronological comparison and difference</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402881</post-id>	</item>
		<item>
		<title>Spurious correlations 0.2 is on CRAN!</title>
		<link>https://www.r-bloggers.com/2026/07/spurious-correlations-0-2-is-on-cran/</link>
		
		<dc:creator><![CDATA[https://pacha.dev/blog]]></dc:creator>
		<pubDate>Wed, 29 Jul 2026 23:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://pacha.dev/blog/2026/07/30/spuriouscorrelations/index.html</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> This release adds feedback from students and instructors</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/spurious-correlations-0-2-is-on-cran/">Spurious correlations 0.2 is on CRAN!</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://pacha.dev/blog/2026/07/30/spuriouscorrelations/index.html"> https://pacha.dev/blog</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<p>The goal of spuriouscorrelations is to keep alive the amazing examples from <a href="https://web.archive.org/web/20230607181247/https://tylervigen.com/spurious-correlations" rel="nofollow" target="_blank">Tyler Vigen</a>. Unfortunately, as of 2023-10-09, the website is down as my students noticed. Therefore, I decided to use the snapshot from the Internet Wayback Machine to save the datasets from 2023-06-07.</p>

<h2>Installation</h2>
<p>You can install the CRAN version of spuriouscorrelations with:</p>
<pre>install.packages(&quot;spuriouscorrelations&quot;)</pre>
<p>You can install the development version of spuriouscorrelations with:</p>
<pre>remotes::install_github(&quot;pachadotdev/spuriouscorrelations&quot;)</pre>

<h2>Example</h2>
<p>The package covers multiple examples for different spurious (and curious) correlations.</p>
<p>Here is a basic example which shows you how to plot a spurious correlation for the variables</p>
<ul>
<li>x: Number of people who drowned by falling into a pool</li>
<li>y: Films Nicolas Cage appeared in</li>
</ul>

<pre>library(spuriouscorrelations)
library(tinyplot)

pool_drownings
   year   x y
1  1999 109 2
2  2000 102 2
3  2001 102 2
4  2002  98 3
5  2003  85 1
6  2004  95 1
7  2005  96 2
8  2006  98 3
9  2007 123 4
10 2008  94 1
11 2009 102 4
cor(pool_drownings$x, pool_drownings$y)
[1] 0.6660043
tinyplot(
  y ~ x,
  data = pool_drownings,
  main = sprintf(&quot;Correlation %s&quot;, round(cor(pool_drownings$x, pool_drownings$y), 3)),
  xlab = &quot;Number of people who drowned by falling into a pool&quot;,
  ylab = &quot;Films Nicolas Cage appeared in&quot;
)</pre>

<p><img src="https://i1.wp.com/pacha.dev/blog/2026/07/30/spuriouscorrelations/unnamed-chunk-1-1.png?w=450&#038;ssl=1" class="img-fluid figure-img"  data-recalc-dims="1"></p>

<p>Converting the data to long format simplifies plotting both variables per year:</p>

<pre>pool_drownings_2 &lt;- reshape(
  pool_drownings, 
  varying = c(&quot;x&quot;, &quot;y&quot;),  # columns to collapse
  v.names = &quot;value&quot;,      # name of the new value column
  timevar = &quot;variable&quot;,   # name of the new ID column
  times = c(&quot;x&quot;, &quot;y&quot;),    # values to populate the ID column
  direction = &quot;long&quot;      # target format
)

pool_drownings_2
     year variable value id
1.x  1999        x   109  1
2.x  2000        x   102  2
3.x  2001        x   102  3
4.x  2002        x    98  4
5.x  2003        x    85  5
6.x  2004        x    95  6
7.x  2005        x    96  7
8.x  2006        x    98  8
9.x  2007        x   123  9
10.x 2008        x    94 10
11.x 2009        x   102 11
1.y  1999        y     2  1
2.y  2000        y     2  2
3.y  2001        y     2  3
4.y  2002        y     3  4
5.y  2003        y     1  5
6.y  2004        y     1  6
7.y  2005        y     2  7
8.y  2006        y     3  8
9.y  2007        y     4  9
10.y 2008        y     1 10
11.y 2009        y     4 11
tinyplot(
  value ~ year | variable, # &quot;|&quot; indicates the groping variable for the legend
  data = pool_drownings_2,
  main = sprintf(&quot;Correlation %s&quot;, round(cor(pool_drownings$x, pool_drownings$y), 3)),
  xlab = &quot;Year&quot;,
  ylab = &quot;Pooled observations&quot;,
  pch = 19 # solid dot shape
)</pre>

<p><img src="https://i2.wp.com/pacha.dev/blog/2026/07/30/spuriouscorrelations/unnamed-chunk-2-1.png?w=450&#038;ssl=1" class="img-fluid figure-img"  data-recalc-dims="1"></p>

<p>How about standarzing the variables to avoid the different scale visibility issue?</p>

<pre>pool_drownings_3 &lt;- pool_drownings

pool_drownings_3$x &lt;- (pool_drownings_3$x - mean(pool_drownings_3$x)) / sd(pool_drownings_3$x)
pool_drownings_3$y &lt;- (pool_drownings_3$y - mean(pool_drownings_3$y)) / sd(pool_drownings_3$y)

pool_drownings_3 &lt;- reshape(
  pool_drownings_3, 
  varying = c(&quot;x&quot;, &quot;y&quot;),  # columns to collapse
  v.names = &quot;value&quot;,      # name of the new value column
  timevar = &quot;variable&quot;,   # name of the new ID column
  times = c(&quot;x&quot;, &quot;y&quot;),    # values to populate the ID column
  direction = &quot;long&quot;      # target format
)

pool_drownings_3
     year variable      value id
1.x  1999        x  0.8952867  1
2.x  2000        x  0.1696333  2
3.x  2001        x  0.1696333  3
4.x  2002        x -0.2450258  4
5.x  2003        x -1.5926679  5
6.x  2004        x -0.5560201  6
7.x  2005        x -0.4523554  7
8.x  2006        x -0.2450258  8
9.x  2007        x  2.3465935  9
10.x 2008        x -0.6596849 10
11.x 2009        x  0.1696333 11
1.y  1999        y -0.2470999  1
2.y  2000        y -0.2470999  2
3.y  2001        y -0.2470999  3
4.y  2002        y  0.6589330  4
5.y  2003        y -1.1531327  5
6.y  2004        y -1.1531327  6
7.y  2005        y -0.2470999  7
8.y  2006        y  0.6589330  8
9.y  2007        y  1.5649658  9
10.y 2008        y -1.1531327 10
11.y 2009        y  1.5649658 11
tinyplot(
  value ~ year | variable, # &quot;|&quot; indicates the groping variable for the legend
  data = pool_drownings_3,
  main = sprintf(&quot;Correlation %s&quot;, round(cor(pool_drownings$x, pool_drownings$y), 3)),
  xlab = &quot;Year&quot;,
  ylab = &quot;Pooled standardized observations&quot;,
  pch = 19, # solid dot shape
  type = &quot;b&quot; # add line to see the trend clearly
)</pre>

<p><img src="https://i1.wp.com/pacha.dev/blog/2026/07/30/spuriouscorrelations/unnamed-chunk-3-1.png?w=450&#038;ssl=1" class="img-fluid figure-img"  data-recalc-dims="1"></p>
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://pacha.dev/blog/2026/07/30/spuriouscorrelations/index.html"> https://pacha.dev/blog</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/spurious-correlations-0-2-is-on-cran/">Spurious correlations 0.2 is on CRAN!</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402883</post-id>	</item>
		<item>
		<title>ntroduction to All Things About bpvars, the R package for Forecasting with Bayesian Panel Vector Autoregressions workshop</title>
		<link>https://www.r-bloggers.com/2026/07/ntroduction-to-all-things-about-bpvars-the-r-package-for-forecasting-with-bayesian-panel-vector-autoregressions-workshop/</link>
		
		<dc:creator><![CDATA[Dariia Mykhailyshyna]]></dc:creator>
		<pubDate>Wed, 29 Jul 2026 12:43:07 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://r-posts.com/?p=19376</guid>

					<description><![CDATA[<p>Join our workshop on Introduction to All Things About bpvars, the R package for Forecasting with Bayesian Panel Vector Autoregressions,  which is a part of our workshops for Ukraine series!  Here’s some more info:  Title: All Things About bpvars, the R package for Forecasting with Bayesian Panel Vector Autoregressions ...</p>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/ntroduction-to-all-things-about-bpvars-the-r-package-for-forecasting-with-bayesian-panel-vector-autoregressions-workshop/">ntroduction to All Things About bpvars, the R package for Forecasting with Bayesian Panel Vector Autoregressions workshop</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="http://r-posts.com/ntroduction-to-all-things-about-bpvars-the-r-package-for-forecasting-with-bayesian-panel-vector-autoregressions-workshop/"> R-posts.com</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<p><span style="font-weight: 400">Join our workshop on Introduction to All Things About bpvars, the R package for Forecasting with Bayesian Panel Vector Autoregressions,</span> <span style="font-weight: 400"> which is a part of our workshops for Ukraine series! </span></p>
<br />
<p><b>Here’s some more info: </b></p>
<br />
<br />
<p><b>Title</b><span style="font-weight: 400">: All Things About bpvars, the R package for Forecasting with Bayesian Panel Vector Autoregressions</span></p>
<p><b>Date</b><span style="font-weight: 400">: Thursday, September 10th, 18:00 – 20:00 CEST (Rome, Berlin, Paris timezone) </span></p>
<p><b>Speaker</b><span style="font-weight: 400">: Tomasz Woźniak is a Bayesian econometrician developing new econometric methods for applied macroeconomic research. He has been a specialised R user for eighteen years, and has recently joined The R Journal as an Associate Editor. He is the author of several R packages, available at https://bsvars.org/, that combine blazingly fast algorithms written in C++ with the convenience of data analysis in R. He works as a senior lecturer at the University of Melbourne, where he has an extensive research, teaching, and engagement portfolio. Tomasz supports Ukraine. Slava Ukrainie!</span></p>
<p><b>Description: </b><span style="font-weight: 400">This session is a unique opportunity to learn to use the bpvars package for forecasting with Bayesian panel vector autoregressions in a wide range of applications spanning:</span></p>
<br />
<p><span style="font-weight: 400">* data preparation,</span></p>
<p><span style="font-weight: 400">* specification of panel vector autoregressions,</span></p>
<p><span style="font-weight: 400">* estimation of the models,</span></p>
<p><span style="font-weight: 400">* estimation with missing observations,</span></p>
<p><span style="font-weight: 400">* forecasting labour market outcomes globally,</span></p>
<p><span style="font-weight: 400">* plotting and reporting predictions of different qualities, including point and density forecasts, marginal, conditional, or restricted forecasts,</span></p>
<p><span style="font-weight: 400">* performing recursive expanding window forecasting,</span></p>
<p><span style="font-weight: 400">* generating forecasting performance reports.</span></p>
<br />
<p><span style="font-weight: 400">A sequence of hands-on exercises that fully prepares attendees to work with the package supports all of this. You are welcome to browse existing resources, including:</span></p>
<br />
<p><span style="font-weight: 400">* bpvars website: https://bsvars.org/bpvars/</span></p>
<p><span style="font-weight: 400">* bpvars CRAN profile: https://cran.r-project.org/package=bpvars</span></p>
<p><span style="font-weight: 400">* package vignette: https://doi.org/10.48550/arXiv.2606.14143</span></p>
<p><span style="font-weight: 400">* other materials: https://bsvars.org/bpvars/#resources</span></p>
<p><span style="font-weight: 400">See you soon!</span></p>
<br />
<p><span style="font-weight: 400">Preparation:</span></p>
<br />
<p><span style="font-weight: 400">This session assumes the attendees know the basics of time series analysis. Install and load the bpvars package, then check the documentation by running the code below. Run the example you will find there in R. If it works, you’re ready to go. Thanks!</span></p>
<p><span style="font-weight: 400">“`</span></p>
<p><span style="font-weight: 400">install.packages(“bpvars”)</span></p>
<p><span style="font-weight: 400">library(bpvars)</span></p>
<p><span style="font-weight: 400">?bpvars</span></p>
<p><b>Minimal registration fee:</b><span style="font-weight: 400"> 20 euro (or 20 USD or 800 UAH)</span></p>
<br />
<br />
<p><span style="font-weight: 400">Please note that the registration confirmation is sent 1 day before the workshop to all registered participants rather than immediately after registration</span></p>
<br />
<p><b>How can I register?</b></p>
<br />
<ul>
	<li style="font-weight: 400"><span style="font-weight: 400">Go to </span><a href="https://bit.ly/3wvwMA6" rel="nofollow" target="_blank"><span style="font-weight: 400">https://bit.ly/3wvwMA6</span></a><span style="font-weight: 400"> or </span><a href="https://bit.ly/4aD5LMC" rel="nofollow" target="_blank"><span style="font-weight: 400">https://bit.ly/4aD5LMC</span></a><span style="font-weight: 400">  or  </span><a href="https://bit.ly/3PFxtNA" rel="nofollow" target="_blank"><span style="font-weight: 400">https://bit.ly/3PFxtNA</span></a><span style="font-weight: 400"> and donate</span><b> at least 20 euro</b><span style="font-weight: 400">. </span><span style="font-weight: 400">Feel free to donate more if you can, all proceeds go directly to support Ukraine.</span></li>
</ul>
<br />
<ul>
	<li style="font-weight: 400"><span style="font-weight: 400">Save your donation receipt (after the donation is processed, there is an option to enter your email address on the website to which the donation receipt is sent)</span></li>
</ul>
<br />
<ul>
	<li style="font-weight: 400"><span style="font-weight: 400">Fill in the</span><a href="https://forms.gle/x1Xc2aPsa1YDD1dD9" rel="nofollow" target="_blank"><span style="font-weight: 400"> registration form</span></a><span style="font-weight: 400">, attaching a screenshot of a donation receipt (please attach the screenshot of the donation receipt that was emailed to you rather than the page you see after donation).</span></li>
</ul>
<br />
<p><span style="font-weight: 400">If you are not personally interested in attending, you can also contribute by sponsoring a participation of a student, who will then be able to participate for free. If you choose to sponsor a student, all proceeds will also go directly to organisations working in Ukraine. You can either sponsor a particular student or you can leave it up to us so that we can allocate the sponsored place to students who have signed up for the waiting list.</span></p>
<br />
<p><b>How can I sponsor a student?</b></p>
<ul>
	<li style="font-weight: 400"><span style="font-weight: 400">Go to </span><a href="https://bit.ly/3wvwMA6" rel="nofollow" target="_blank"><span style="font-weight: 400">https://bit.ly/3wvwMA6</span></a><span style="font-weight: 400"> or </span><a href="https://bit.ly/4aD5LMC" rel="nofollow" target="_blank"><span style="font-weight: 400">https://bit.ly/4aD5LMC</span></a><span style="font-weight: 400">  or </span><a href="https://bit.ly/3PFxtNA" rel="nofollow" target="_blank"><span style="font-weight: 400">https://bit.ly/3PFxtNA</span></a><span style="font-weight: 400"> and donate </span><b>at least 20 euro </b><span style="font-weight: 400">(or 17 GBP or 20 USD or 800 UAH). </span><span style="font-weight: 400">Feel free to donate more if you can, all proceeds go to support Ukraine!</span></li>
</ul>
<br />
<ul>
	<li style="font-weight: 400"><span style="font-weight: 400">Save your donation receipt (after the donation is processed, there is an option to enter your email address on the website to which the donation receipt is sent)</span></li>
</ul>
<br />
<ul>
	<li style="font-weight: 400"><span style="font-weight: 400">Fill in the </span><a href="https://forms.gle/VdAkKshBjicvnrWq5" rel="nofollow" target="_blank"><span style="font-weight: 400">sponsorship form</span></a><span style="font-weight: 400">, attaching the screenshot of the donation receipt (please attach the screenshot of the donation receipt that was emailed to you rather than the page you see after the donation). You can indicate whether you want to sponsor a particular student or we can allocate this spot ourselves to the students from the waiting list. You can also indicate whether you prefer us to prioritize students from developing countries when assigning place(s) that you sponsored.</span></li>
</ul>
<br />
<br />
<p><span style="font-weight: 400">If you are a university student and cannot afford the registration fee, you can also sign up for the </span><b>waiting list</b> <a href="https://forms.gle/sokQuowKYLx4AQdg9" rel="nofollow" target="_blank"><span style="font-weight: 400">here</span></a><span style="font-weight: 400">. (Note that you are not guaranteed to participate by signing up for the waiting list).</span></p>
<br />
<br />
<p><span style="font-weight: 400">You can also find more information about this workshop series,  a schedule of our future workshops as well as a list of our past workshops which you can get the recordings &#038; materials </span><a href="http://bit.ly/3wBeY4S" rel="nofollow" target="_blank"><span style="font-weight: 400">here</span></a><span style="font-weight: 400">.</span></p>
<br />
<p><span style="font-weight: 400">Looking forward to seeing you during the workshop!</span></p>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<p><span style="font-weight: 400"> </span></p>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br /><hr style="border-top: black solid 1px" /><a href="http://r-posts.com/ntroduction-to-all-things-about-bpvars-the-r-package-for-forecasting-with-bayesian-panel-vector-autoregressions-workshop/" rel="nofollow" target="_blank">ntroduction to All Things About bpvars, the R package for Forecasting with Bayesian Panel Vector Autoregressions workshop</a> was first posted on July 29, 2026 at 12:43 pm.<br />
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://r-posts.com/ntroduction-to-all-things-about-bpvars-the-r-package-for-forecasting-with-bayesian-panel-vector-autoregressions-workshop/"> R-posts.com</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/ntroduction-to-all-things-about-bpvars-the-r-package-for-forecasting-with-bayesian-panel-vector-autoregressions-workshop/">ntroduction to All Things About bpvars, the R package for Forecasting with Bayesian Panel Vector Autoregressions workshop</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402867</post-id>	</item>
		<item>
		<title>Using ghost text and next edit suggestions to learn agentic coding</title>
		<link>https://www.r-bloggers.com/2026/07/using-ghost-text-and-next-edit-suggestions-to-learn-agentic-coding/</link>
		
		<dc:creator><![CDATA[Seascapemodels]]></dc:creator>
		<pubDate>Mon, 27 Jul 2026 14:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://www.seascapemodels.org/posts/2026-07-28-next-edit-suggestions/</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>I’m a big fan of Github Copilots ghost text and next edit suggestions. As a data analyst they give you much more control over the pace and direction of analysis code than a full AI agent. They also let you practice the core skill an agent needs ...</p></div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/using-ghost-text-and-next-edit-suggestions-to-learn-agentic-coding/">Using ghost text and next edit suggestions to learn agentic coding</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://www.seascapemodels.org/posts/2026-07-28-next-edit-suggestions/"> Seascapemodels</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
 





<p>I’m a big fan of Github Copilots ghost text and next edit suggestions. As a data analyst they give you much more control over the pace and direction of analysis code than a full AI agent. They also let you practice the core skill an agent needs from you: writing a clear specification.</p>
<p>I’ll walk through it in R, but the same ideas apply in any language. I’m assuming you’re on VScode with the Copilot extension installed. This should work with the free or paid plans (though I haven’t checked free myself).</p>
<section id="start-with-ghost-text" class="level2">
<h2 class="anchored" data-anchor-id="start-with-ghost-text">Start with ghost text</h2>
<p>Ghost text is the greyed-out completion that appears as you type. Say you have a long-format dataset with timeseries for three species:</p>
<pre>library(dplyr)
library(ggplot2)
dat &lt;- data.frame(
    time = rep(1:10, 3),
    species = rep(c(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;), each = 10),
    value = c(rnorm(10, mean = 5), rnorm(10, mean = 10), rnorm(10, mean = 15))
)</pre>
<p>You want to filter to one species, fit a linear model to its timeseries, pull out the slope, and make a labelled plot. Start typing the code for a single species and ghost text fills in the rest of the line. Here I’ve typed <code>m1 &lt;- lm(value ~</code> and Copilot offers the completion in transparent text (note change in image after the <code>~</code>):</p>
<p><img src="https://i2.wp.com/www.seascapemodels.org/posts/2026-07-28-next-edit-suggestions/1_ghost-text-example.png?w=578&#038;ssl=1" class="img-fluid" data-recalc-dims="1"></p>
<p>Press tab to accept. Working one line at a time, you end up with the code for species A:</p>
<pre>datA &lt;- dat |&gt; filter(species == &quot;A&quot;)
m1 &lt;- lm(value ~ time, data = datA)
coef(m1)[&quot;time&quot;]

ggplot(datA, aes(x = time, y = value)) +
    geom_point() +
    geom_smooth(method = &quot;lm&quot;, se = FALSE) +
    labs(
        title = &quot;Species A Time Series&quot;,
        x = &quot;Time&quot;,
        y = &quot;Value&quot;
    )</pre>
<p>Notice we’re not trying to be general yet. We’re developing our ideas for a single case, species A. We know we’ll want to generalise later, but we’re not worrying about it now. This is the same discipline that makes agents work well: get one concrete case right first, then automate it.</p>
</section>
<section id="turn-on-next-edit-suggestions" class="level2">
<h2 class="anchored" data-anchor-id="turn-on-next-edit-suggestions">Turn on next edit suggestions</h2>
<p>Next edit suggestions go a step further than ghost text. Instead of completing the line you’re on, Copilot predicts the <em>next change you’ll want to make elsewhere</em> and points you to it.</p>
<p>Click the octocat icon in the bottom right of the VScode window and turn on <strong>Next Edit Suggestions</strong>. I recommend leaving this off most of the time — it’s distracting when it suggests edits you don’t want — and switching it on for jobs like this one.</p>
<p>Now click above the species A code and start typing the name of a function to wrap it in. As soon as I write the <code>fit_fun &lt;- function(species_name)</code> header, Copilot spots that the hardcoded <code>&quot;A&quot;</code> needs to change, and flags it with an arrow in the gutter:</p>
<p><img src="https://i2.wp.com/www.seascapemodels.org/posts/2026-07-28-next-edit-suggestions/2_next-edit-suggestion-part1.png?w=578&#038;ssl=1" class="img-fluid" data-recalc-dims="1"></p>
<p>Press tab and it walks you through the edits needed to generalise. It replaces <code>species == &quot;A&quot;</code> with <code>species == species_name</code>, and further down it rewrites the plot title from the literal <code>&quot;Species A Time Series&quot;</code> to a <code>paste()</code> call that builds the title from <code>species_name</code>:</p>
<p><img src="https://i2.wp.com/www.seascapemodels.org/posts/2026-07-28-next-edit-suggestions/3_next-edit-suggestion-part2.png?w=578&#038;ssl=1" class="img-fluid" data-recalc-dims="1"></p>
<p>Tab through each suggestion and you land on a working, generalised function:</p>
<pre>fit_fun &lt;- function(species_name) {
    datA &lt;- dat |&gt; filter(species == species_name)
    m1 &lt;- lm(value ~ time, data = datA)
    coef(m1)[&quot;time&quot;]

    ggplot(datA, aes(x = time, y = value)) +
        geom_point() +
        geom_smooth(method = &quot;lm&quot;, se = FALSE) +
        labs(
            title = paste(&quot;Species&quot;, species_name, &quot;Time Series&quot;),
            x = &quot;Time&quot;,
            y = &quot;Value&quot;
        )
}

fit_fun(&quot;A&quot;)</pre>
<p>The single-species code was the specification and then Copilot did the mechanical work of generalising it. This is a good scaffold for thinking about agentic programming, where you write a clear spec and the agent does the automation.</p>
<p>The big difference from a true agent is that ghost text and next edit don’t run your R code and iterate to fix errors. They just predict edits. But that makes them a safe place to build the skills.</p>
</section>
<section id="drive-it-with-comments" class="level2">
<h2 class="anchored" data-anchor-id="drive-it-with-comments">Drive it with comments</h2>
<p>You can run the same next-edit approach with text only. Write out a recipe for what you want as comments, then start typing under the first step. Ghost text and next edit take over and help you write the rest.</p>
<p>Here’s a simple recipe:</p>
<pre># Simulate a new dataset of abundance at x-y coordinates

# plot a 2D map

# fit a model with interaction between x and y</pre>
<p>With just the comments in place and the cursor after the simulation, Copilot reads the recipe ahead of it:</p>
<p><img src="https://i1.wp.com/www.seascapemodels.org/posts/2026-07-28-next-edit-suggestions/4.png?w=578&#038;ssl=1" class="img-fluid" data-recalc-dims="1"></p>
<p>Then suggests a next edit suggestion after the following comment:</p>
<p><img src="https://i2.wp.com/www.seascapemodels.org/posts/2026-07-28-next-edit-suggestions/5.png?w=578&#038;ssl=1" class="img-fluid" data-recalc-dims="1"></p>
<p>Keep going and it writes the model for the final step, picking up the interaction from the comment <code># fit a model with interaction between x and y</code>:</p>
<p><img src="https://i2.wp.com/www.seascapemodels.org/posts/2026-07-28-next-edit-suggestions/6.png?w=578&#038;ssl=1" class="img-fluid" data-recalc-dims="1"></p>
<p>The finished block writes itself from the recipe:</p>
<p>A few tips. I set Copilot’s eagerness to <strong>High</strong> so suggestions come up quickly. Sometimes you need to type the first few characters of a line to kickstart the ghost text.</p>
<p>The clearer and more specific your comments, the closer the suggestions will be to what you actually wanted.</p>


</section>

 
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://www.seascapemodels.org/posts/2026-07-28-next-edit-suggestions/"> Seascapemodels</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/using-ghost-text-and-next-edit-suggestions-to-learn-agentic-coding/">Using ghost text and next edit suggestions to learn agentic coding</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402854</post-id>	</item>
		<item>
		<title>June 2026 Top 40 New CRAN Packages</title>
		<link>https://www.r-bloggers.com/2026/07/june-2026-top-40-new-cran-packages/</link>
		
		<dc:creator><![CDATA[Joseph Rickert]]></dc:creator>
		<pubDate>Mon, 27 Jul 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://rworks.dev/posts/june-2026-top-40-new-cran-packages/</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>Four hundred twelve new packages were submitted to CRAN in June. Here are my Top 40 picks in nineteen categories: Bioarchaeology, Biology, Climate Studies, Computational Methods, Ecology, Epidemiology, Finance, Functional Data Analysis, Machine ...</p></div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/june-2026-top-40-new-cran-packages/">June 2026 Top 40 New CRAN Packages</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://rworks.dev/posts/june-2026-top-40-new-cran-packages/"> R Works</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
 





<p>Four hundred twelve new packages were submitted to CRAN in June. Here are my Top 40 picks in nineteen categories: Bioarchaeology, Biology, Climate Studies, Computational Methods, Ecology, Epidemiology, Finance, Functional Data Analysis, Machine Learning, Medical Statistics, Networks, Pharmacokinetics, Probability, Programming, Psychometrics, Risk Analysis, Statistics, Time Series, and Utilities.</p>
<div class="columns">
<div class="column" style="width:45%;">
<section id="bioarchaeology" class="level3">
<h3 class="anchored" data-anchor-id="bioarchaeology">Bioarchaeology</h3>
<p><a href="https://cran.r-project.org/package=baytaAAR" rel="nofollow" target="_blank">baytaAAR</a> v1.0.3: Provides Bayesian age estimation for bioarchaeological skeletal data using ordinal probit regression models implemented in <code>JAGS</code> and <code>NIMBLE</code>. The package is designed to handle multiple ordinal traits of adult individuals and incorporates a Gompertz prior on age to reflect population-level mortality. It accounts for estimation uncertainties and supports full customization of model parameters and Markov Chain Monte Carlo settings. For more details, see <a href="https://onlinelibrary.wiley.com/doi/10.1002/ajpa.70289" rel="nofollow" target="_blank">Müller-Scheeßel et al. (2026)</a>. There are five vignettes including <a href="https://cran.r-project.org/web/packages/baytaAAR/vignettes/baytaAAR.html" rel="nofollow" target="_blank">Introduction</a> and <a href="https://cran.r-project.org/web/packages/baytaAAR/vignettes/mathematical_background.html" rel="nofollow" target="_blank">Mathematical background</a>.</p>
<p><a href="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/baytoAAR.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-1" rel="nofollow" target="_blank"><img src="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/baytoAAR.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of distribution of age to death" data-recalc-dims="1"></a></p>
</section>
<section id="biology" class="level3">
<h3 class="anchored" data-anchor-id="biology">Biology</h3>
<p><a href="https://cran.r-project.org/package=power.nb" rel="nofollow" target="_blank">power.nb</a> v0.1.0: Provides functions for estimating statistical power and required sample sizes in differential abundance microbiome studies using negative binomial models and includes tools for simulation-based power analysis and sample size estimation using generalized additive models (GAMs), and visualization utilities for exploring the relationship between power, effect size, abundance, and sample size. The methods are based on <a href="https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0318820" rel="nofollow" target="_blank">Agronah and Bolker (2025)</a>. See the <a href="https://cran.r-project.org/web/packages/power.nb/vignettes/stub.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/powervb.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-2" rel="nofollow" target="_blank"><img src="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/powervb.png?w=578&#038;ssl=1" class="img-fluid" alt="Contour plot showing power for various combinations of mean abundance and fold change" data-recalc-dims="1"></a></p>
</section>
<section id="climate-studies" class="level3">
<h3 class="anchored" data-anchor-id="climate-studies">Climate Studies</h3>
<p><a href="https://cran.r-project.org/package=clim4health" rel="nofollow" target="_blank">clim4health</a> v0.1.0: Provides functions to obtain, transform and export climate data, including reanalyses, seasonal forecasts and hindcasts, and weather stations for their use in epidemiological analyses. Features include downscaling, verification, spatiotemporal aggregation and threshold-based indicators. See <a href="https://www.nature.com/articles/s41598-026-45067-2" rel="nofollow" target="_blank">Duzenli et al. (2026)</a> for downscaling methods and <a href="https://www.sciencedirect.com/science/article/abs/pii/S1364815217302219" rel="nofollow" target="_blank">Manubens et al. (2018)</a> for verification methods. There are six vignettes, including <a href="https://cran.r-project.org/web/packages/clim4health/vignettes/clim4health_s2dv_cubes.html" rel="nofollow" target="_blank">Introduction</a> and <a href="https://cran.r-project.org/web/packages/clim4health/vignettes/clim4health_overview.html" rel="nofollow" target="_blank">Overview</a>.</p>
</section>
<section id="computational-methods" class="level3">
<h3 class="anchored" data-anchor-id="computational-methods">Computational Methods</h3>
<p><a href="https://cran.r-project.org/package=momst" rel="nofollow" target="_blank">momst</a> v0.1.1: Provides functions to solve the Multi-Criteria Minimum Spanning Tree problem on complete weighted graphs by combining the Non-dominated Sorting Genetic Algorithm II with optional Pareto local search operators. Chromosomes are represented as Prufer sequences so that every random individual decodes to a valid spanning tree (Cayley’s theorem), avoiding repair operators. Four solver variants are provided: NSGA-II, Path Relinking, Pareto Local Search, and Tabu Search. See <a href="https://ieeexplore.ieee.org/document/7969432" rel="nofollow" target="_blank">Parraga-Alava et al. (2017)</a> for background. There are two vignettes: <a href="https://cran.r-project.org/web/packages/momst/vignettes/getting-started.html" rel="nofollow" target="_blank">Getting Started</a> and <a href="https://cran.r-project.org/web/packages/momst/vignettes/momst-variants.html" rel="nofollow" target="_blank">Comparing the Four MO-MST Variants</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/momst.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-3" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/momst.png?w=578&#038;ssl=1" class="img-fluid" alt="Graphs of spanning tree variants" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=nmathopencl" rel="nofollow" target="_blank">nmathopencl</a> v0.8.3: Ships statistical and mathematical routines from the <code>R</code> internal <a href="https://github.com/SurajGupta/r-source/blob/master/src/nmath/nmath.h" rel="nofollow" target="_blank"><code>nmath</code></a> (<code>Mathlib</code>) as <a href="https://en.wikipedia.org/wiki/OpenCL" rel="nofollow" target="_blank"><code>OpenCL</code></a> <code>C</code> sources under directory <code>inst/cl/</code>, with <code>R</code> wrappers. Uses the GPU when <code>OpenCL</code> is available at compile time and falls back to <code>stats</code> equivalents otherwise. Aimed at package developers building custom kernels (for example Bayesian GLMs via suggested package <code>glmbayes</code>) using <code>opencltools</code> kernel loaders and related helpers. There are thirteen vignettes, including <a href="https://cran.r-project.org/web/packages/nmathopencl/vignettes/Chapter-00.html" rel="nofollow" target="_blank">Package Overview</a> and <a href="https://cran.r-project.org/web/packages/nmathopencl/vignettes/Chapter-10.html" rel="nofollow" target="_blank">Case study</a>.</p>
<p><a href="https://cran.r-project.org/package=sparsediff" rel="nofollow" target="_blank">sparsediff</a> v0.4.0: Implements bindings for the <code>SparseDiffEngine</code> <code>C</code> library, the sparse Jacobian and Hessian differentiation backend used by <code>CVXPY</code> for its Disciplined Nonlinear Programming extension. Provides low-level routines for building nonlinear expression graphs and evaluating sparse derivatives, intended as a backend for higher-level modeling layers such as <code>CVXR</code>. This is the <code>R</code> analog of the <code>sparsediffpy</code> <code>Python</code> package and wraps the same <code>C</code> library. See the <a href="https://cran.r-project.org/web/packages/sparsediff/vignettes/sparsediff.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://cran.r-project.org/package=StochSimR" rel="nofollow" target="_blank">StochSimR</a> v1.1.0: Implements a modular simulation engine for a wide range of stochastic processes. Provides exact and approximate simulation methods for Poisson processes, Brownian motion, discrete- and continuous-time Markov chains, birth-death processes, the Yule pure-birth process, infinitesimal generator matrix utilities, Markovian queuing systems with exact steady-state statistics, Levy processes, Merton jump-diffusion models, Hawkes self-exciting processes, geometric Brownian motion, and Ornstein-Uhlenbeck mean-reverting diffusions. See <a href="https://link.springer.com/book/10.1007/978-0-387-21617-1" rel="nofollow" target="_blank">Glasserman (2003)</a> and <a href="https://link.springer.com/book/10.1007/978-0-387-69033-9" rel="nofollow" target="_blank">Asmussen &#038; Glynn (2007)</a> for background and the <a href="https://cran.r-project.org/web/packages/StochSimR/vignettes/introduction.html" rel="nofollow" target="_blank">vignette</a> for an introduction.</p>
<p><a href="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/StochSimR.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-4" rel="nofollow" target="_blank"><img src="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/StochSimR.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of simulated Brownian Motion" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/web/packages/Uno/vignettes/Uno.html" rel="nofollow" target="_blank">Uno</a> v2.7.4: Provides bindings to <a href="https://unosolver.readthedocs.io/en/latest/" rel="nofollow" target="_blank">Uno</a> (Unifying Nonlinear Optimization), a <code>C++</code> solver for smooth nonlinearly constrained optimization that unifies Lagrange-Newton methods, including sequential quadratic programming and interior-point methods, by decomposing them into interacting building blocks (constraint-relaxation, inequality-handling, Hessian, and globalization strategies). The framework is described in <a href="https://arxiv.org/abs/2406.13454" rel="nofollow" target="_blank">Vanaret and Leyffer (2024)</a>. See the <a href="https://cran.r-project.org/web/packages/Uno/vignettes/Uno.html" rel="nofollow" target="_blank">vignette</a> for an example.</p>
</section>
<section id="ecology" class="level3">
<h3 class="anchored" data-anchor-id="ecology">Ecology</h3>
<p><a href="https://cran.r-project.org/package=BayesFR" rel="nofollow" target="_blank">BayesFR</a> v1.0.1: Enables fitting various functional response models for single- and multi-prey experiments by providing nonlinear prediction functions for <code>brms</code> and provides a framework for easily testing hypotheses on trophic interactions. Models can incorporate covariates such as temperature gradients, experimental treatment variables, or random effects that account for grouping in experimental units. See <a href="https://besjournals.onlinelibrary.wiley.com/doi/10.1111/2041-210X.14372" rel="nofollow" target="_blank">Rosenbaum and Rall (2018)</a> and <a href="https://besjournals.onlinelibrary.wiley.com/doi/10.1111/2041-210X.13039" rel="nofollow" target="_blank">Rosenbaum et al. (2024)</a> for background and the <a href="https://cran.r-project.org/web/packages/BayesFR/vignettes/bayesfr-intro.html" rel="nofollow" target="_blank">vignette</a> to get started.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/BayesFR.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-5" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/BayesFR.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of number of eaten prey against prey abundance " data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=nicheR" rel="nofollow" target="_blank">nicheR</a> v0.1.0: Provides tools to construct and define virtual ecological niches using ellipsoid geometries. It enables the identification and extraction of suitable environmental areas, simulation of species occurrence points with various sampling strategies, and visualization of niche boundaries and simulated occurrences in both environmental and geographic space. See <a href="https://onlinelibrary.wiley.com/doi/10.1111/j.1365-2699.2008.02041.x" rel="nofollow" target="_blank">Etherington et al. (2009)</a> and <a href="https://nsojournals.onlinelibrary.wiley.com/doi/10.1111/ecog.01961" rel="nofollow" target="_blank">Qiao et al. (2015)</a> for background. There are six vignettes, including <a href="https://cran.r-project.org/web/packages/nicheR/vignettes/plotting_vignette.html" rel="nofollow" target="_blank">Visualizing ellipsoids in environmental space</a> and <a href="https://cran.r-project.org/web/packages/nicheR/vignettes/virtual_communities.html" rel="nofollow" target="_blank">Virtual community simulation</a>.</p>
<p><a href="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/nicheR.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-6" rel="nofollow" target="_blank"><img src="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/nicheR.png?w=578&#038;ssl=1" class="img-fluid" alt="Stability Plot" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=spacc" rel="nofollow" target="_blank">spacc</a> v0.8.3: Implements <code>kNN</code> and <code>kNCN</code> sampling methods with a <code>C++</code> backend to compute spatial species accumulation curves. Supports Hill numbers, beta diversity partitioning, coverage-based rarefaction and extrapolation, phylogenetic diversity (Faith’s PD, mean pairwise distance, mean nearest taxon distance), functional diversity accumulation, diversity-area relationships, endemism-area curves, sampling-effort correction and fragmentation analysis, and species-area relationship models based on extreme value theory. See <a href="https://esajournals.onlinelibrary.wiley.com/doi/10.1890/13-0133.1" rel="nofollow" target="_blank">Chao et al. (2014)</a> and <a href="https://onlinelibrary.wiley.com/doi/10.1111/j.1466-8238.2009.00490.x" rel="nofollow" target="_blank">Baselga (2010)</a> for background. There are seven vignettes, including <a href="https://cran.r-project.org/web/packages/spacc/vignettes/quickstart.html" rel="nofollow" target="_blank">Getting Started</a> and <a href="https://cran.r-project.org/web/packages/spacc/vignettes/diversity.html" rel="nofollow" target="_blank">Diversity Accumulation</a>.</p>
<p><a href="https://rworks.dev/posts/june-2026-top-40-new-cran-packages/spacc.svg" class="lightbox" data-gallery="quarto-lightbox-gallery-7" rel="nofollow" target="_blank"><img src="https://rworks.dev/posts/june-2026-top-40-new-cran-packages/spacc.svg" class="img-fluid" alt="Plot of saptial Hill number accumulation"></a></p>
<p><a href="https://cran.r-project.org/package=TemporalModelR" rel="nofollow" target="_blank">TemporalModelR</a> v0.3.0: Provides functions to assist with three major steps for building temporally-explicit ecological niche and species distribution models: (i) preprocessing species and environmental data, (ii) building a niche model and generating temporally-explicit predictions, and (iii) model postprocessing to explore spatiotemporal trends. See <a href="https://besjournals.onlinelibrary.wiley.com/doi/10.1111/2041-210X.13564" rel="nofollow" target="_blank">Ingenloff and Peterson (2021</a> and <a href="https://nsojournals.onlinelibrary.wiley.com/doi/10.1111/ecog.03187" rel="nofollow" target="_blank">Blonder (2018)</a> for the methodological and theoretical foundations. Modeling with a <a href="https://cran.r-project.org/web/packages/TemporalModelR/vignettes/V3a_GLM.html" rel="nofollow" target="_blank">GLM</a> and <a href="https://cran.r-project.org/web/packages/TemporalModelR/vignettes/V3c_RF.html" rel="nofollow" target="_blank">Modeling with a Random Forest</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/Temporal.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-8" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/Temporal.png?w=578&#038;ssl=1" class="img-fluid" alt="Random Forest Marginal Prediction Curves" data-recalc-dims="1"></a></p>
</section>
<section id="epidemiology" class="level3">
<h3 class="anchored" data-anchor-id="epidemiology">Epidemiology</h3>
<p><a href="https://cran.r-project.org/package=SmokingHistoryGenerator" rel="nofollow" target="_blank">SmokingHistoryGenerator</a> v7.0.0: Implements an interface to the Cancer Intervention and Surveillance Modeling Network (<a href="https://cisnet.cancer.gov/resources/model-registry/lung-models/" rel="nofollow" target="_blank">CISNET</a>) Smoking History Generator microsimulation engine, which synthesizes individual smoking histories (initiation, cessation, intensity) and ages at death from calibrated initiation, cessation, cigarettes-per-day, and mortality tables. See <a href="https://onlinelibrary.wiley.com/doi/10.1111/j.1539-6924.2011.01775.x" rel="nofollow" target="_blank">Jeon et al. (2012)</a> for background and look <a href="https://github.com/NCI-CISNET/shg-r" rel="nofollow" target="_blank">here</a> to get started.</p>
</section>
<section id="finance" class="level3">
<h3 class="anchored" data-anchor-id="finance">Finance</h3>
<p><a href="https://cran.r-project.org/package=CamelRatiosIndex" rel="nofollow" target="_blank">CamelRatiosIndex</a> v1.0.0: Computes a composite year-on-year index for bank performance assessment using the CAMEL framework (Capital Adequacy, Asset Quality, Management Efficiency, Earnings, Liquidity). The multivariate weighting scheme employs factor analysis with robust covariance estimation to derive communality-based weights from the correlation matrix of CAMEL ratios. Provides functions for index computation, visualization, and comparison across banks and time periods. The methodology is described in <a href="https://stm.bookpi.org/CMWCPIAAMR/article/view/10917" rel="nofollow" target="_blank">Ayimah et al. (2023a)</a> and <a href="https://stm.bookpi.org/CMWCPIAAMR/issue/view/1083" rel="nofollow" target="_blank">Ayimah et al. (2023b)</a>. See the <a href="https://cran.r-project.org/web/packages/CamelRatiosIndex/vignettes/introduction.html" rel="nofollow" target="_blank">vignette</a> for an introduction.</p>
<p><a href="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/Camel.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-9" rel="nofollow" target="_blank"><img src="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/Camel.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of CAMEL index" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=JumpDiffSim" rel="nofollow" target="_blank">JumpDiffSim</a> v0.1.0: Implements the <a href="https://www.sciencedirect.com/science/article/abs/pii/0304405X76900222" rel="nofollow" target="_blank">Merton (1976)</a> and <a href="https://pubsonline.informs.org/doi/10.1287/mnsc.48.8.1086.166" rel="nofollow" target="_blank">Kou (2002)</a> jump-diffusion models through a unified S4 object-oriented interface. Provides exact compound-Poisson asset price simulation, maximum likelihood parameter estimation with Hessian-based standard errors, Wald-type confidence intervals, European option pricing via the Merton analytic series expansion, and publication-quality diagnostic plots. All functionality operates entirely offline without market data dependencies. See the <a href="https://cran.r-project.org/web/packages/JumpDiffSim/vignettes/JumpDiffSim-intro.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/Jump.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-10" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/Jump.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of simulated asset price" data-recalc-dims="1"></a></p>
</section>
<section id="functional-data-analysis" class="level3">
<h3 class="anchored" data-anchor-id="functional-data-analysis">Functional Data Analysis</h3>
<p><a href="https://cran.r-project.org/package=fda.vi" rel="nofollow" target="_blank">fda.vi</a> v1.0.0: Implements a variational Expectation-Maximization algorithm for smoothing one or multiple functional observations via basis function selection. The algorithm estimates all model parameters simultaneously and automatically, while accounting for within-curve correlation to provide a flexible and computationally efficient framework for smoothing correlated functional data. See <a href="https://arxiv.org/abs/2405.20758" rel="nofollow" target="_blank">da Cruz et al. (2024)</a> for a description of the algorithm and the <a href="https://cran.r-project.org/web/packages/fda.vi/vignettes/introduction.html" rel="nofollow" target="_blank">vignette</a> for examples.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/fdavi.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-11" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/fdavi.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of VEM curve" data-recalc-dims="1"></a></p>
</section>
<section id="machine-learning" class="level3">
<h3 class="anchored" data-anchor-id="machine-learning">Machine Learning</h3>
<p><a href="https://cran.r-project.org/package=svmodt" rel="nofollow" target="_blank">svmodt</a> v0.1.0: Implements Support Vector Machine Oblique Decision Trees. Recursively builds classification trees using linear Support Vector Machine hyperplanes at each node instead of axis-parallel splits, creating oblique decision boundaries. Features include multiple feature selection methods, dynamic feature subset strategies, class weight support for imbalanced datasets, pruning, and feature penalization. See the <a href="https://cran.r-project.org/web/packages/svmodt/vignettes/introduction.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/svmodt.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-12" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/svmodt.png?w=578&#038;ssl=1" class="img-fluid" alt="Scatterplot showing SVM decision boundary" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=yaap" rel="nofollow" target="_blank">yaap</a> v1.0.0: Fits archetypal analysis models, including Euclidean, probabilistic, kernel, and directional variants. Methods include classical archetypal analysis from <a href="https://www.tandfonline.com/doi/abs/10.1080/00401706.1994.10485840" rel="nofollow" target="_blank">Cutler and Breiman (1994)</a>, PCHA and kernel variants from <a href="https://www.sciencedirect.com/science/article/abs/pii/S0925231211006060" rel="nofollow" target="_blank">Mørup and Hansen (2012)</a>, probabilistic archetypal analysis from <a href="https://link.springer.com/article/10.1007/s10994-015-5498-8" rel="nofollow" target="_blank">Seth and Eugster (2016</a>, directional archetypal analysis from <a href="https://www.frontiersin.org/journals/neuroscience/articles/10.3389/fnins.2022.911034/full" rel="nofollow" target="_blank">Olsen et al. (2022)</a>, AA++ initialization from <a href="https://proceedings.neurips.cc/paper_files/paper/2019/file/7f278ad602c7f47aa76d1bfc90f20263-Paper.pdf" rel="nofollow" target="_blank">Mair and Sjölund (2023)</a>, coreset-style initialization from <a href="https://proceedings.neurips.cc/paper_files/paper/2019/file/7f278ad602c7f47aa76d1bfc90f20263-Paper.pdf" rel="nofollow" target="_blank">Mair and Brefeld (2019)</a>, and adapted AIC from <a href="https://ieeexplore.ieee.org/document/8015385" rel="nofollow" target="_blank">Suleman (2017)</a>. There are four vignettes including an <a href="https://cran.r-project.org/web/packages/yaap/vignettes/introduction.html" rel="nofollow" target="_blank">Introduction</a> and <a href="https://cran.r-project.org/web/packages/yaap/vignettes/tidymodels.html" rel="nofollow" target="_blank">Tidymodels Workflows</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/yaap.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-13" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/yaap.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of archetype positions in feature space" data-recalc-dims="1"></a></p>
</section>
<section id="medical-statistics" class="level3">
<h3 class="anchored" data-anchor-id="medical-statistics">Medical Statistics</h3>
<p><a href="https://cran.r-project.org/package=BayesTSM" rel="nofollow" target="_blank">BayesTSM</a> v1.0.1: In screening programs, individuals are usually followed up and tested (screened) for the development of a disease. The target disease often develops progressively in stages; for example, healthy (state 1), pre-state disease (state 2), and the disease state (state 3). When the pre-state disease is found during screening, an intervention may prevent disease progression.<code>BayesTSM</code> functions estimate a progressive three-state model with censoring due to intervention using Bayesian estimation methods, as described in <a href="https://projecteuclid.org/journals/annals-of-applied-statistics/volume-17/issue-2/A-Bayesian-accelerated-failure-time-model-for-interval-censored-three/10.1214/22-AOAS1669.full" rel="nofollow" target="_blank">Klausch et al. (2023)</a>. See the <a href="https://cran.r-project.org/web/packages/BayesTSM/vignettes/bayestsm-userguide.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/BayesTSM.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-14" rel="nofollow" target="_blank"><img src="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/BayesTSM.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of posterior predictive priors" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=bayprior" rel="nofollow" target="_blank">bayprior</a> v0.2.12: Provides a toolkit for constructing, validating, and justifying Bayesian priors in clinical trial settings. Implements expert elicitation via quantile matching, the roulette method, and moment matching, linear and logarithmic expert pooling, and prior-data conflict diagnostics. Includes a fully modular <code>Shiny</code> application for interactive use. See <a href="https://www.jstor.org/stable/2982063?origin=crossref" rel="nofollow" target="_blank">Box (1980)</a> and <a href="https://shelf.sites.sheffield.ac.uk/" rel="nofollow" target="_blank">Oakley and O’Hagan (2010)</a> for background. There are six vignettes, including <a href="https://cran.r-project.org/web/packages/bayprior/vignettes/bayprior-introduction.html" rel="nofollow" target="_blank">Introduction</a> and <a href="https://cran.r-project.org/web/packages/bayprior/vignettes/robust-priors.html" rel="nofollow" target="_blank">Robust, Sceptical, and Power Priors</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/bayprior.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-15" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/bayprior.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of Bayes factor vs power prior weight" data-recalc-dims="1"></a></p>
</section>
</div><div class="column" style="width:10%;">

</div><div class="column" style="width:45%;">
<section id="networks" class="level3">
<h3 class="anchored" data-anchor-id="networks">Networks</h3>
<p><a href="https://cran.r-project.org/package=netify" rel="nofollow" target="_blank">netify</a> v1.5.3: Provides functions to build, validate, analyze, and visualize network data from dyadic, event, matrix, <code>igraph</code>, and <code>network</code> inputs. Supports cross-sectional, longitudinal, bipartite, and multi-layer networks, with conversion helpers for common modeling workflows and plotting utilities for exploratory analysis. Network methods are described in <a href="https://www.amazon.com/Social-Network-Analysis-Applications-Structural/dp/0521387078" rel="nofollow" target="_blank">Wasserman and Faust (1994)</a>, <a href="https://www.cambridge.org/highereducation/books/inferential-network-analysis/A7797D36A24647AA1F900CE7EF694C7E#overview" rel="nofollow" target="_blank">Cranmer et al. (2021)</a>, and <a href="https://www.cambridge.org/core/journals/political-science-research-and-methods/article/abs/taking-dyads-seriously/823804FA29B988156A574C3F44280317" rel="nofollow" target="_blank">Minhas et al. (2022)</a>. There are four vignettes, including <a href="https://cran.r-project.org/web/packages/netify/vignettes/quickstart_inference.html" rel="nofollow" target="_blank">Quickstart</a> and <a href="https://cran.r-project.org/web/packages/netify/vignettes/internals.html" rel="nofollow" target="_blank">Internals</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/netify.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-16" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/netify.png?w=578&#038;ssl=1" class="img-fluid" alt="Plots of network over time" data-recalc-dims="1"></a></p>
</section>
<section id="pharmacokinetics" class="level3">
<h3 class="anchored" data-anchor-id="pharmacokinetics">Pharmacokinetics</h3>
<p><a href="https://cran.r-project.org/package=admixr2" rel="nofollow" target="_blank">admixr2</a> v0.2.0: Provides functions to fit pharmacokinetic/pharmacodynamic (PK/PD) models to aggregate-level data (mean vector and covariance matrix per study) rather than individual-level data. Integrates with the <code>nlmixr2</code>/<code>rxode2</code> ecosystem via four estimation methods: a First-Order analytical estimator, a Monte Carlo estimator, a Gauss-Hermite quadrature estimator, and an Iterative Reweighting Monte Carlo estimator. Methods are based on <a href="https://link.springer.com/article/10.1007/s10928-021-09760-1" rel="nofollow" target="_blank">Välitalo (2021)</a> software described in van de <a href="https://link.springer.com/article/10.1007/s10928-025-10011-w" rel="nofollow" target="_blank">Beek et al. (2025)</a>. See the <a href="https://cran.r-project.org/web/packages/admixr2/vignettes/admixr2.html" rel="nofollow" target="_blank">vignette</a> to get started.</p>
<p><a href="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/admixr2.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-17" rel="nofollow" target="_blank"><img src="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/admixr2.png?w=578&#038;ssl=1" class="img-fluid" alt="Study diagnostic plots" data-recalc-dims="1"></a></p>
</section>
<section id="probability" class="level3">
<h3 class="anchored" data-anchor-id="probability">Probability</h3>
<p><a href="https://cran.r-project.org/package=GLBFP" rel="nofollow" target="_blank">GLBFP</a> v0.5.2: Implements nonparametric density estimation with Averaged Shifted Histogram, Linear Blend Frequency Polygon, and General Linear Blend Frequency Polygon estimators and provides pointwise and grid-based estimation workflows, sparse-prefix grid-count computation, plotting helpers, and plug-in bandwidth selection. Methodological background follows <a href="https://onlinelibrary.wiley.com/doi/book/10.1002/9780470316849" rel="nofollow" target="_blank">Scott (1992)</a>, <a href="https://www.tandfonline.com/doi/abs/10.1080/01621459.1985.10477163" rel="nofollow" target="_blank">Terrell and Scott (1985)</a>, and <a href="https://link.springer.com/article/10.1007/s10463-023-00883-5" rel="nofollow" target="_blank">Carbon and Duchesne (2024)</a>. There are nine vignettes, including <a href="https://cran.r-project.org/web/packages/GLBFP/vignettes/getting-started.html" rel="nofollow" target="_blank">Getting started</a> and <a href="https://cran.r-project.org/web/packages/GLBFP/vignettes/GLBFP_introduction.html" rel="nofollow" target="_blank">Package overview</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/GLBFP.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-18" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/GLBFP.png?w=578&#038;ssl=1" class="img-fluid" alt="Density plot" data-recalc-dims="1"></a></p>
</section>
<section id="programming" class="level3">
<h3 class="anchored" data-anchor-id="programming">Programming</h3>
<p><a href="https://cran.r-project.org/package=rsgl" rel="nofollow" target="_blank">rsgl</a> v0.1.0: Generates plots from a database connection and an <code>SGL</code> statement. <code>SGL</code> is a graphics language designed to look and feel like <code>SQL</code> and is especially useful for those familiar with <code>SQL</code> who want to specify plots in a similar manner. The <code>SGL</code> language is described in <a href="https://arxiv.org/abs/2505.14690" rel="nofollow" target="_blank">Chapman (2025)</a>. See the vignettes <a href="https://cran.r-project.org/web/packages/rsgl/vignettes/rsgl.html" rel="nofollow" target="_blank">Get started</a> and <a href="https://cran.r-project.org/web/packages/rsgl/vignettes/example-gallery.html" rel="nofollow" target="_blank">Example gallery</a>.</p>
<p><a href="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/rsgl.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-19" rel="nofollow" target="_blank"><img src="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/rsgl.png?w=578&#038;ssl=1" class="img-fluid" alt="Visualization of age as an angle " data-recalc-dims="1"></a></p>
</section>
<section id="psychometrics" class="level3">
<h3 class="anchored" data-anchor-id="psychometrics">Psychometrics</h3>
<p><a href="https://cran.r-project.org/package=easyRasch2" rel="nofollow" target="_blank">easyRasch2</a> v1.1.0: Streamlines reproducible Rasch measurement theory analyses for ordinal item-response data, combining estimation routines from <code>eRm</code>, <code>psychotool</code>, <code>mirt</code>, <code>iarm</code>, and <code>lavaan</code> with consistent diagnostic, plotting, and reporting layers. Covers the four basic psychometric criteria summarized by <a href="https://onlinelibrary.wiley.com/doi/10.1111/sms.13908" rel="nofollow" target="_blank">Christensen et al. (2021)</a>: unidimensionality, local independence, ordered response category thresholds, and invariance across subgroups, together with item fit, targeting, reliability, category functioning, and descriptive item-response plots. A distinguishing feature is the use of simulation-based critical values to replace rule-of-thumb cutoffs. See the <a href="https://cran.r-project.org/web/packages/easyRasch2/vignettes/easyRasch2.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/easyRasch2.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-20" rel="nofollow" target="_blank"><img src="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/easyRasch2.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of latent trait probabilities" data-recalc-dims="1"></a></p>
</section>
<section id="risk-analysis" class="level3">
<h3 class="anchored" data-anchor-id="risk-analysis">Risk Analysis</h3>
<p><a href="https://cran.r-project.org/package=riskutility" rel="nofollow" target="_blank">riskutility</a> v0.1.0: Provides comprehensive methods to measure disclosure risk and data utility for anonymized and synthetic data. Implements attribution-based risk metrics including Correct Attribution Probability, Targeted CAP, Within Equivalence Class Attribution Probability, and Risk of Attribute Prediction-Induced Disclosure. Also provides distance-based privacy metrics such as Distance to Closest Record, Nearest Neighbor Distance Ratio, and Identical Match Share. Utility assessment includes propensity score analysis, distribution comparisons, and various statistical tests. Methods are based on <a href="https://link.springer.com/chapter/10.1007/978-3-319-99771-1_9" rel="nofollow" target="_blank">Taub et al. (2018)</a>. See the <a href="https://cran.r-project.org/web/packages/riskutility/vignettes/riskutility.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/riskutility.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-21" rel="nofollow" target="_blank"><img src="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/riskutility.png?w=578&#038;ssl=1" class="img-fluid" alt="histogram of distance to cloest record" data-recalc-dims="1"></a></p>
</section>
<section id="statistics" class="level3">
<h3 class="anchored" data-anchor-id="statistics">Statistics</h3>
<p><a href="https://cran.r-project.org/package=bayesqm" rel="nofollow" target="_blank">bayesqm</a> v0.1.0: Provides a Bayesian factor-analytic framework for Q methodology. Fits a low-rank factor model to Q-sort data with a Student-t likelihood and a hierarchical normal prior on loadings, samples the posterior with <code>Stan</code>, resolves rotational ambiguity via the MatchAlign post-processing of <a href="https://projecteuclid.org/journals/bayesian-analysis/volume--1/issue--1/Efficiently-Resolving-Rotational-Ambiguity-in-Bayesian-Matrix-Sampling-with-Matching/10.1214/25-BA1544.full" rel="nofollow" target="_blank">Poworoznek et al. (2025)</a> and returns posterior summaries including credible intervals for loadings and factor scores, probabilistic dominant-factor membership, distinguishing and consensus statements, and PSIS-LOO-based factor enumeration following <a href="https://link.springer.com/article/10.1007/s11222-016-9696-4" rel="nofollow" target="_blank">Vehtari et al. (2017)</a> with the <a href="https://projecteuclid.org/journals/bayesian-analysis/volume--1/issue--1/Uncertainty-in-Bayesian-Leave-One-Out-Cross-Validation-Based-Model/10.1214/25-BA1569.full" rel="nofollow" target="_blank">Sivula et al. (2025)</a> parsimony rule. See the <a href="https://cran.r-project.org/web/packages/bayesqm/vignettes/bayesqm-intro.html" rel="nofollow" target="_blank">vignette</a> to get started.</p>
<p><a href="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/bayesqm.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-22" rel="nofollow" target="_blank"><img src="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/bayesqm.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of ELPD peak vs. K" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=depthR" rel="nofollow" target="_blank">depthR</a> v0.1.8: Provides efficient implementations of multivariate statistical depth functions in arbitrary dimension. Implements Mahalanobis depth, Tukey halfspace depth, Liu simplicial depth, projection depth, spatial depth, depth-based medians, central regions, outlier detection, and depth-depth plots. <code>C++</code> backends via <code>Rcpp</code> and <code>RcppEigen</code> ensure performance at large n and d. See <a href="https://projecteuclid.org/journals/annals-of-statistics/volume-18/issue-1/On-a-Notion-of-Data-Depth-Based-on-Random-Simplices/10.1214/aos/1176347507.full" rel="nofollow" target="_blank">Liu (1990)</a>, <a href="https://projecteuclid.org/journals/annals-of-statistics/volume-28/issue-2/General-notions-of-statistical-depth-function/10.1214/aos/1016218226.full" rel="nofollow" target="_blank">Serfling and Zuo (2000)</a>, and <a href="https://www.pnas.org/doi/abs/10.1073/pnas.97.4.1423" rel="nofollow" target="_blank">Vardi and Zhang (2000)</a> for background, and the <a href="https://cran.r-project.org/web/packages/depthR/vignettes/depthR.html" rel="nofollow" target="_blank">vignette</a> for an introduction.</p>
<p><a href="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/depthR.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-23" rel="nofollow" target="_blank"><img src="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/depthR.png?w=578&#038;ssl=1" class="img-fluid" alt="The depth-depth plot is the multivariate analog of the QQ-plot" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=dppca" rel="nofollow" target="_blank">dppca</a> v0.1.0: Provides tools for differentially private principal component analysis visualization and includes functions for estimating private principal component directions, constructing private scree and proportion of variance explained summaries, and visualizing two-dimensional PCA score summaries using additive and sparse histogram mechanisms. Group-wise score visualizations and an interactive <code>shiny</code> app are also provided. See <a href="https://onlinelibrary.wiley.com/doi/10.1002/sam.70053" rel="nofollow" target="_blank">Kim and Jung (2025)</a>, <a href="https://www.emerald.com/fttcs/article-abstract/9/3-4/211/1332491/The-Algorithmic-Foundations-of-Differential?redirectedFrom=fulltext" rel="nofollow" target="_blank">Dwork and Roth (2014)</a> and <a href="https://arxiv.org/abs/2501.14095" rel="nofollow" target="_blank">Ramsay and Spicker (2025)</a> for background. There are four vignettes, including <a href="https://cran.r-project.org/web/packages/dppca/vignettes/algorithms.html" rel="nofollow" target="_blank">Algorithms</a> and <a href="https://cran.r-project.org/web/packages/dppca/vignettes/pc_direction.html" rel="nofollow" target="_blank">PC Directions in dppca</a>.</p>
<p><a href="https://cran.r-project.org/package=ernest" rel="nofollow" target="_blank">ernest</a> v1.2.5: Bayesian evidence estimation and posterior inference with the nested sampling algorithm, described in <a href="https://projecteuclid.org/journals/bayesian-analysis/volume-1/issue-4/Nested-sampling-for-general-Bayesian-computation/10.1214/06-BA127.full" rel="nofollow" target="_blank">Skilling (2006)</a> and <a href="https://projecteuclid.org/journals/statistics-surveys/volume-17/issue-none/Nested-sampling-methods/10.1214/23-SS144.full" rel="nofollow" target="_blank">Buchner (2023)</a>, along with S3 methods for simulating uncertainty and creating visualizations. See the vignettes <a href="https://cran.r-project.org/web/packages/ernest/vignettes/nested-sampling-with-ernest.html" rel="nofollow" target="_blank">Nested Sampling</a> and <a href="https://cran.r-project.org/web/packages/ernest/vignettes/more-ernest-runs.html" rel="nofollow" target="_blank">More Examples</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/ernest.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-24" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/ernest.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot showing ability to properly integrate across multimodal likelihood surfaces. " data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=gkrreg" rel="nofollow" target="_blank">gkrreg</a> v0.4.0: Implements the Gaussian Kernel Robust Regression method proposed by <a href="https://www.sciencedirect.com/science/article/abs/pii/S0925231216315508" rel="nofollow" target="_blank">De Carvalho, Lima Neto and Ferreira (2017)</a>, which re-weights observations iteratively using the Gaussian kernel so that poorly-fitted observations receive small weights, yielding resistance to Y-space outliers, X-space outliers and leverage points. Provides three estimators for the kernel width hyper-parameter: Caputo, pairwise median, and residual variance. Inference is accomplished via an analytic sandwich variance estimator or via bootstrap. Six real datasets from the robust regression literature are included to facilitate reproducible comparisons. See the <a href="https://cran.r-project.org/web/packages/gkrreg/vignettes/introduction.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/gkrreg.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-25" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/gkrreg.png?w=578&#038;ssl=1" class="img-fluid" alt="Three residual plots " data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=picreg" rel="nofollow" target="_blank">picreg</a> v0.1.4 Implements the Pivotal Information Criterion developed by <a href="https://arxiv.org/abs/2603.04172" rel="nofollow" target="_blank">Sardy, van Cutsem, and van de Geer</a>. PIC is a general framework to improve on BIC and LASSO for fitting sparse regression linear models in which the regularization parameter 𝜆 is selected automatically from a pivotal statistic. Functions fit the resulting estimators across six response distributions, Gaussian, binomial, Poisson, exponential, Gumbel, and Cox, and three sparsity-inducing penalties; (LASSO), the Smoothly Clipped Absolute Deviation (SCAD), and Minimax Concave Penalty (MCP). See the <a href="https://cran.r-project.org/web/packages/picreg/vignettes/vignette.html" rel="nofollow" target="_blank">vignette</a> for an introduction.</p>
<p><a href="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/picreg.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-26" rel="nofollow" target="_blank"><img src="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/picreg.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot showing individual survival curves" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=SimplexRegression" rel="nofollow" target="_blank">SimplexRegression</a> v0.1.5: Fits and analyzes simplex regression models with either fixed or parametric mean link functions. Implements the simplex probability density function, cumulative distribution function, quantile function, random number generation, and variance evaluation. Offers several fixed and parametric link functions for the mean submodel, tools for residual analysis and diagnostic plotting, hypothesis testing procedures, and influence measures such as Cook’s distance and leverage. Includes the Scout Score criterion for model selection, enabling comprehensive inference and diagnostic analysis within the simplex regression framework. See <a href="https://www.sciencedirect.com/science/article/pii/0047259X9190008P" rel="nofollow" target="_blank">Barndorff-Nielsen and Jorgensen (1991)</a> and <a href="https://www.sciencedirect.com/science/article/abs/pii/S0307904X25007863" rel="nofollow" target="_blank">Justino and Cribari-Neto (2026)</a> for more details and the <a href="https://cran.r-project.org/web/packages/SimplexRegression/vignettes/relative-humidity.html" rel="nofollow" target="_blank">vignette</a> for examples.</p>
<p><a href="https://cran.r-project.org/package=vbm" rel="nofollow" target="_blank">vbm</a> v0.1.0: Provides methods for variance-based sensitivity analysis and weighting estimators in observational studies based on the methodology by <a href="https://academic.oup.com/biomet/article-abstract/112/1/asae040/7731116?redirectedFrom=fulltext&#038;login=false" rel="nofollow" target="_blank">Huang &#038; Pimentel (2025)</a> Includes bootstrap inference, bias bounds estimation, and visualization tools for sensitivity parameters. See the <a href="https://cran.r-project.org/web/packages/vbm/vignettes/vbm.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/vbm.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-27" rel="nofollow" target="_blank"><img src="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/vbm.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot showing variables that should be prioritized for adjustment based on both treatment and outcome, while traditional love plot only considers treatment imbalance" data-recalc-dims="1"></a></p>
</section>
<section id="time-series" class="level3">
<h3 class="anchored" data-anchor-id="time-series">Time Series</h3>
<p><a href="https://cran.r-project.org/package=bvars" rel="nofollow" target="_blank">bvars</a> v1.0: Provides fast and efficient procedures for Bayesian estimation and forecasting using state-of-the-art vector autoregressions. Includes the model proposed by <a href="https://www.tandfonline.com/doi/full/10.1080/07350015.2018.1451336" rel="nofollow" target="_blank">Chan (2020)</a>, a Bayesian vector autoregression with Minnesota priors and a flexible structure of the error term that permits conditional multivariate normal or Student’s t distributions, as well as homoskedastic or heteroskedastic specifications with a common volatility modelled by centred or non-centred Stochastic Volatility. Additional features include predictive analyses using density forecasting and forecast-error variance decompositions. See <a href="https://cran.r-project.org/web/packages/bvars/readme/README.html" rel="nofollow" target="_blank">README</a> for an example.</p>
<p><a href="https://cran.r-project.org/package=fable.intermittent" rel="nofollow" target="_blank">fable.intermittent</a> v0.1.1: Extends the <code>fable</code> framework to support forecasting methods specifically designed for intermittent time series data, where demand occurs sporadically with many zero values. All methods produce probabilistic forecasts returned as ‘distributional’ objects. The returned forecasts can be used to evaluate accuracy, plot and print the results. Methods include: <a href="https://www.tandfonline.com/doi/abs/10.1080/07350015.1989.10509750" rel="nofollow" target="_blank">Harvey, Fernandes (1989)</a>, <a href="https://www.sciencedirect.com/science/article/abs/pii/S016920700300013X" rel="nofollow" target="_blank">Willemain, Smart, Schwarz (2004)</a> and several others. See the <a href="https://cran.r-project.org/web/packages/fable.intermittent/vignettes/fable.intermittent.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/fable.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-28" rel="nofollow" target="_blank"><img src="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/fable.png?w=578&#038;ssl=1" class="img-fluid" alt="Time series with multiple forecasts" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=muse" rel="nofollow" target="_blank">muse</a> v0.1.0: Implements the Power / Trend / Seasonal (PTS) model, a unified state-space framework based on the Multiple Source of Error model. It brings the trend, seasonal and irregular component models of <a href="https://www.cambridge.org/core/books/forecasting-structural-time-series-models-and-the-kalman-filter/CE5E112570A56960601760E786A5E631" rel="nofollow" target="_blank">Harvey (1989)</a>, <a href="https://academic.oup.com/book/16563?login=false" rel="nofollow" target="_blank">Durbin and Koopman (2012)</a> and others together under a single estimation, selection and forecasting interface, with an optional Box-Cox power transformation. Models are estimated by maximum likelihood through the Kalman filter and smoother, with automatic component selection by information criteria. See the <a href="https://cran.r-project.org/web/packages/muse/vignettes/pts.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/muse.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-29" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/muse.png?w=578&#038;ssl=1" class="img-fluid" alt="Time series with forecst" data-recalc-dims="1"></a></p>
</section>
<section id="utilities" class="level3">
<h3 class="anchored" data-anchor-id="utilities">Utilities</h3>
<p><a href="https://cran.r-project.org/package=ahocorasick" rel="nofollow" target="_blank">ahocorasick</a> v0.2.0: Provides fast multi-pattern string matching using the ’<code>Aho-Corasick</code> algorithm, powered by the <code>Rust</code> <code>aho-corasick</code> crate. It builds reusable automatons for detecting matches, counting matches, locating characters, extracting matched text, and replacing matches in character vectors. See <a href="https://dl.acm.org/doi/10.1145/360825.360855" rel="nofollow" target="_blank">Aho and Corasick (1975)</a> for more information on the <code>Aho-Corasick</code> algorithm and the <a href="https://cran.r-project.org/web/packages/ahocorasick/vignettes/benchmarks.html" rel="nofollow" target="_blank">vignette</a> for an example.</p>
<p><a href="https://cran.r-project.org/package=mx.crypto" rel="nofollow" target="_blank">mx.crypto</a> v0.2.0: Provides <code>Olm</code> and <code>Megolm</code> encryption ratchet primitives for the <a href="https://matrix.org/" rel="nofollow" target="_blank">Matrix messaging protocol</a>, wrapping the <code>vodozemac</code> <code>Rust</code> crate. Provides device-key generation, one-time-key management, 1:1 <code>Olm</code> sessions, and <code>Megolm</code> group sessions. Pairs with the <code>mx.api</code> package, which handles <code>Matrix HTTP</code> transport. See the <a href="https://cran.r-project.org/web/packages/mx.crypto/vignettes/security-audit.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://cran.r-project.org/package=pkgmatch" rel="nofollow" target="_blank">pkgmatch</a> v0.5.4: Provides functions to find <code>R</code> packages from <code>CRAN</code>, <code>rOpenSci</code>, or <code>Bioconductor</code> corpora. Packages can be matched to general text descriptions, to names of installed packages, or to local paths to entire source repositories. The package is used to list the most similar packages for each new submission to the <code>rOpenSci</code> software <a href="https://zenodo.org/records/18885936" rel="nofollow" target="_blank">peer-review program</a>. There are three vignettes, including an <a href="https://cran.r-project.org/web/packages/pkgmatch/vignettes/pkgmatch.html" rel="nofollow" target="_blank">introduction</a> and <a href="https://cran.r-project.org/web/packages/pkgmatch/vignettes/A_extended-use-case.html" rel="nofollow" target="_blank">Example applications</a>.</p>
</section>
</div>
</div>



 
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://rworks.dev/posts/june-2026-top-40-new-cran-packages/"> R Works</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/june-2026-top-40-new-cran-packages/">June 2026 Top 40 New CRAN Packages</a>]]></content:encoded>
					
		
		<enclosure url="https://rworks.dev/posts/june-2026-top-40-new-cran-packages/momst.png" length="0" type="image/png" />

		<post-id xmlns="com-wordpress:feed-additions:1">402843</post-id>	</item>
		<item>
		<title>GPopt for R: Bayesian and conformal optimization of black-box functions and hyperparameter tuning</title>
		<link>https://www.r-bloggers.com/2026/07/gpopt-for-r-bayesian-and-conformal-optimization-of-black-box-functions-and-hyperparameter-tuning/</link>
		
		<dc:creator><![CDATA[T. Moudiki]]></dc:creator>
		<pubDate>Sun, 26 Jul 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://thierrymoudiki.github.io//blog/2026/07/26/r/GPopt</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> GPopt for R: Bayesian and conformal optimization of black-box functions and hyperparameter tuning</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/gpopt-for-r-bayesian-and-conformal-optimization-of-black-box-functions-and-hyperparameter-tuning/">GPopt for R: Bayesian and conformal optimization of black-box functions and hyperparameter tuning</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://thierrymoudiki.github.io//blog/2026/07/26/r/GPopt"> T. Moudiki's Webpage - R</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<p>This post describes the <code>R</code> version of Python’s <a href="https://github.com/Techtonique/GPopt" rel="nofollow" target="_blank">GPopt</a> 
(<a href="https://docs.techtonique.net/GPopt/GPopt.html" rel="nofollow" target="_blank">https://docs.techtonique.net/GPopt/GPopt.html</a>), a package for
‘Bayesian’ optimization of black-box functions and machine learning hyperparameter tuning, using Gaussian
Process Regression and other conformalized surrogates. The package is available on 
<a href="https://github.com/Techtonique/GPopt_r" rel="nofollow" target="_blank">GitHub</a>, and through the <a href="https://techtonique.r-universe.dev/builds" rel="nofollow" target="_blank">R universe</a>.</p>

<p>Keep in mind that this package is for Machine Learning hyperparameter tuning: <strong>the global minimum won’t always be found, but this isn’t an <em>issue</em>, since it means you aren’t overfitting the training set</strong>.</p>

<p>It’s ported the same way as <a href="https://github.com/Techtonique/nnetsauce_r" rel="nofollow" target="_blank">nnetsauce for R</a> was: with <code>uv</code> to
create an isolated Python virtual environment containing the Python <code>GPopt</code> package, and <code>reticulate</code> to call
into it from R. Every function in this R package is a thin wrapper that returns the underlying Python object;
the general rule is: <strong>object accesses with <code>.</code>’s in Python are replaced by <code>$</code>’s in R.</strong></p>

<p>See this post for the technique: <a href="https://thierrymoudiki.github.io/blog/2025/12/17/r/python/new-nnetsauce-R-uv" rel="nofollow" target="_blank">Finally figured out a way to port python packages to R using uv and reticulate</a>.</p>

<h2 id="install">Install</h2>

<h3 id="1-create-a-python-virtual-environment-with-uv">1. Create a Python virtual environment with <code>uv</code></h3>

<pre># pip install uv # if necessary
uv venv venv
source venv/bin/activate      # on Windows: venv\Scripts\activate
uv pip install pip GPopt
</pre>

<p>Keep track of where <code>venv/</code> lives – you’ll pass its path as <code>venv_path</code> to every function in this package.</p>

<h3 id="2-install-the-r-package">2. Install the R package</h3>

<pre>install.packages(&quot;remotes&quot;)
remotes::install_github(&quot;Techtonique/GPopt_r&quot;) 
</pre>

<p><code>reticulate</code> will be installed automatically as a dependency.</p>

<h2 id="examples">Examples</h2>

<h3 id="minimizing-the-branin-function">Minimizing the Branin function</h3>

<p>This is a standard test function for optimization algorithms. <code>GPOpt</code> is more suitable for expensive black-box functions, but this is a good example to illustrate the usage of the package.</p>

<pre>library(GPopt)

branin &lt;- function(x) {
  x1 &lt;- x[1]; x2 &lt;- x[2]
  term1 &lt;- (x2 - (5.1 * x1^2) / (4 * pi^2) + (5 * x1) / pi - 6)^2
  term2 &lt;- 10 * (1 - 1 / (8 * pi)) * cos(x1)
  term1 + term2 + 10
}

opt &lt;- GPOpt(
  lower_bound = c(-5, 0),
  upper_bound = c(10, 15),
  objective_func = branin,
  n_init = 10,
  n_iter = 40,
  venv_path = &quot;./venv&quot;
)

opt$optimize(verbose = 1L)
print(opt$x_min)  # best parameters
print(opt$y_min)  # best objective value
</pre>

<h3 id="tuning-a-scikit-learn-models-hyperparameters">Tuning a scikit-learn model’s hyperparameters</h3>

<pre>library(GPopt)

sklearn &lt;- get_sklearn(venv_path = &quot;./venv&quot;)
RandomForestClassifier &lt;- sklearn$ensemble$RandomForestClassifier

X &lt;- as.matrix(iris[, 1:4])
y &lt;- as.integer(iris$Species) - 1L

mlopt &lt;- MLOptimizer(scoring = &quot;accuracy&quot;, cv = 5, venv_path = &quot;./venv&quot;)

param_config &lt;- list(
  n_estimators = list(bounds = c(10, 300), dtype = &quot;int&quot;),
  max_depth    = list(bounds = c(1, 20),   dtype = &quot;int&quot;)
)

mlopt$optimize(
  X_train = X, y_train = y,
  estimator_class = RandomForestClassifier(),
  param_config = param_config,
  verbose = 1L
)

print(mlopt$get_best_parameters())
print(mlopt$get_best_score())
</pre>

<h3 id="bayesian-optimization-with-early-stopping">Bayesian optimization with early stopping</h3>

<pre>library(GPopt)

opt &lt;- BOstopping(
  f = branin,
  bounds = rbind(c(-5, 10), c(0, 15)),
  venv_path = &quot;./venv&quot;
)
result &lt;- opt$optimize(n_iter = 100L)
</pre>

<h3 id="using-a-custom-conformalized-surrogate-model">Using a custom (conformalized) surrogate model</h3>

<pre>library(GPopt)

sklearn &lt;- get_sklearn(venv_path = &quot;./venv&quot;)
ns &lt;- get_nnetsauce(venv_path = &quot;./venv&quot;)

opt &lt;- GPOpt(
  lower_bound = c(-5, 0),
  upper_bound = c(10, 15),
  objective_func = branin,
  acquisition=&quot;ucb&quot;,
  method=&quot;splitconformal&quot;,
  surrogate_obj = ns$PredictionInterval(sklearn$ensemble$RandomForestRegressor()),
  venv_path = &quot;./venv&quot;
)
opt$optimize(verbose = 1L)
</pre>

<p><img src="https://i0.wp.com/thierrymoudiki.github.io/images/2024-01-29/2024-01-29-image1.png?w=578&#038;ssl=1" alt="xxx" class="img-responsive" data-recalc-dims="1" /></p>

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://thierrymoudiki.github.io//blog/2026/07/26/r/GPopt"> T. Moudiki's Webpage - R</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/gpopt-for-r-bayesian-and-conformal-optimization-of-black-box-functions-and-hyperparameter-tuning/">GPopt for R: Bayesian and conformal optimization of black-box functions and hyperparameter tuning</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402828</post-id>	</item>
		<item>
		<title>Some useful equations for biological processes</title>
		<link>https://www.r-bloggers.com/2026/07/some-useful-equations-for-biological-processes/</link>
		
		<dc:creator><![CDATA[Andrea Onofri]]></dc:creator>
		<pubDate>Thu, 23 Jul 2026 22:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://www.statforbiology.com/posts/nls_usefulEquations.html</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>Biological phenomena are often studied by examining how a numerical variable, usually called the response (e.g., the weight or height of an organism), is affected by another variable, usually called the predictor (e.g., time or fertiliser applic...</p></div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/some-useful-equations-for-biological-processes/">Some useful equations for biological processes</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://www.statforbiology.com/posts/nls_usefulEquations.html"> Statforbiology</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
 





<p>Biological phenomena are often studied by examining how a numerical variable, usually called the <em>response</em> (e.g., the weight or height of an organism), is affected by another variable, usually called the <em>predictor</em> (e.g., time or fertiliser application rate). These ‘predictor-response’ relationships are commonly described using <strong>models</strong>, which express the response as a mathematical function of the predictor. In general, a model can be written as:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20f(X,%20%5Ctheta)"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?Y"> is the response, <img src="https://latex.codecogs.com/png.latex?X"> is the predictor, and <img src="https://latex.codecogs.com/png.latex?%5Ctheta"> is a collection of parameters, usually denoted by symbols, such as the letters of the Roman or Greek alphabet. The element <img src="https://latex.codecogs.com/png.latex?f"> is the <em>function</em>, which determines the shape of the relationship when plotted on an <em>x–y</em> graph.</p>
<p>Because mathematical modelling plays such a central role in biology and many other scientific disciplines, biologists need to be familiar with the most important mathematical functions. More importantly, they need to be able to “read” these functions and use their parameters to describe, interpret, and quantify biological processes. With this aim in mind, I have compiled a collection of the mathematical functions most commonly encountered in biology, explaining the meaning of their parameters, with particular emphasis on their biological interpretation rather than their mathematical properties.</p>
<section id="curve-shapes" class="level1">
<h1>Curve shapes</h1>
<p>Functions are often classified according to the shape they exhibit when plotted on an <em>x–y</em> graph. This approach is adopted, for example, in Ratkowsky (1990), and the classification presented below is largely based on that work.</p>
<ul>
<li>Polynomials
<ol type="1">
<li>Straight line function</li>
<li>Quadratic polynomial function</li>
</ol></li>
<li>Concave/Convex curves (no inflection)
<ol type="1">
<li>Exponential function</li>
<li>Asymptotic function / Negative exponential function</li>
<li>Power function</li>
<li>Logarithmic function</li>
<li>Rectangular hyperbola</li>
</ol></li>
<li>Sigmoidal curves
<ol type="1">
<li>Logistic function</li>
<li>Gompertz function</li>
<li>Modified Gompertz function</li>
<li>Log-logistic function</li>
<li>Weibull (type-1) function</li>
<li>Weibull (type-2) function</li>
</ol></li>
<li>Curves with maxima/minima
<ol type="1">
<li>Peaked sigmoidal function</li>
<li>Bragg function</li>
<li>Lorentz function</li>
<li>Beta function</li>
</ol></li>
</ul>
<p>I have chosen to include a relatively large number of functions, so this post is necessarily rather long. To make navigation easier, you can first inspect Figure 1 to identify the type of curve of interest and then use the links above to jump directly to the corresponding section.</p>
<p>Throughout this post, <img src="https://latex.codecogs.com/png.latex?X"> denotes the predictor, <img src="https://latex.codecogs.com/png.latex?Y"> denotes the response, and the letters of the Roman alphabet (<img src="https://latex.codecogs.com/png.latex?a">, <img src="https://latex.codecogs.com/png.latex?b">, <img src="https://latex.codecogs.com/png.latex?c">, …) denote the model parameters, which determine the shape of the function.</p>
<div class="cell">
<div class="cell-output-display">
<div id="fig-1" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://i1.wp.com/www.statforbiology.com/posts/nls_usefulEquations_files/figure-html/fig-1-1.png?w=578&#038;ssl=1" class="img-fluid figure-img" style="width:95.0%" data-recalc-dims="1">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure 1: The shapes of the most important functions. The different colors indicate the possible different shapes of the same function, with different parameters. In the case of the Bragg/Lorentz function, the red color indicate the Bragg function and the blue color indicate the Lorentz function (same parameter values).
</figcaption>
</figure>
</div>
</div>
</div>
</section>
<section id="polynomials" class="level1">
<h1>Polynomials</h1>
<p>Polynomials form a class of their own because their flexible shapes allow them to approximate a wide variety of biological processes, at least over a restricted range of the predictor. The mathematical tractation is very simple, but their main limitation is that they cannot describe asymptotic processes, which are extremely common in biology. Moreover, as the polynomial degree increases, their shapes become increasingly complex and often lack a meaningful biological interpretation.</p>
<section id="straight-line-function" class="level2">
<h2 class="anchored" data-anchor-id="straight-line-function">Straight-line function</h2>
<p>The simplest polynomial is the straight line, with equation:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20+%20bX%20%5Cqquad%5Cqquad%20(1)"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?a"> is the value of <img src="https://latex.codecogs.com/png.latex?Y"> when <img src="https://latex.codecogs.com/png.latex?X%20=%200">, and <img src="https://latex.codecogs.com/png.latex?b"> is the slope, that is, the change in <img src="https://latex.codecogs.com/png.latex?Y"> associated with a one-unit increase in <img src="https://latex.codecogs.com/png.latex?X">. When <img src="https://latex.codecogs.com/png.latex?b%3E0">, <img src="https://latex.codecogs.com/png.latex?Y"> increases as <img src="https://latex.codecogs.com/png.latex?X"> increases; when <img src="https://latex.codecogs.com/png.latex?b%3C0">, it decreases.</p>
<p>Because of their simplicity, straight lines are mainly used to approximate biological responses over a limited range of the predictor. Should you need it, an example of fitting a straight line to research data is given elsewhere <a href="https://www.statforbiology.com/posts/nls_modelFitting.html#straight-line-function" rel="nofollow" target="_blank">at this link</a>.</p>
</section>
<section id="quadratic-polynomial-function" class="level2">
<h2 class="anchored" data-anchor-id="quadratic-polynomial-function">Quadratic polynomial function</h2>
<p>The quadratic polynomial is described by the equation:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20+%20bX%20+%20cX%5E2%20%5Cqquad%5Cqquad%20(2)"></p>
<p>This equation describes a U-shaped curve (a parabola), which may open upwards or downwards depending on the sign of <img src="https://latex.codecogs.com/png.latex?c">. If <img src="https://latex.codecogs.com/png.latex?c%3E0">, the parabola opens upwards; otherwise, it opens downwards.</p>
<p>The parameter <img src="https://latex.codecogs.com/png.latex?a"> represents the value of <img src="https://latex.codecogs.com/png.latex?Y"> when <img src="https://latex.codecogs.com/png.latex?X=0">, whereas <img src="https://latex.codecogs.com/png.latex?b"> and <img src="https://latex.codecogs.com/png.latex?c"> determine how the response changes as the predictor varies. To better understand the role of these parameters, we can examine the first derivative of Eq. (2). In R, this can be obtained with the <code>D()</code> function, which differentiates an expression with respect to a specified variable:</p>
<div class="cell">
<pre>D(expr = expression(a + b*X + c*X^2), name = &quot;X&quot;)</pre>
<div class="cell-output cell-output-stdout">
<pre>b + c * (2 * X)</pre>
</div>
</div>
<p>The derivative is not constant but varies with the value of <img src="https://latex.codecogs.com/png.latex?X"> and, in particular, <img src="https://latex.codecogs.com/png.latex?b"> represent the variation of <img src="https://latex.codecogs.com/png.latex?Y"> around the point <img src="https://latex.codecogs.com/png.latex?X%20=%200">. The stationary point, that is, the point where the derivative is zero, occurs at:</p>
<p><img src="https://latex.codecogs.com/png.latex?X_m%20=%20-%5Cfrac%7Bb%7D%7B2c%7D"></p>
<p>This point is a <strong>minimum</strong> when <img src="https://latex.codecogs.com/png.latex?c%3E0"> and a <strong>maximum</strong> when <img src="https://latex.codecogs.com/png.latex?c%3C0">.</p>
<p>The corresponding response is</p>
<p><img src="https://latex.codecogs.com/png.latex?Y_%7B%5Ctextrm%7Bmax%7D%7D%20=%20%5Cfrac%7B4ac-b%5E2%7D%7B4c%7D"></p>
<p>In practice, biologists often use only one branch of the parabola to approximate biological responses showing either a concave or a convex trend over a limited range of the predictor. Check <a href="https://www.statforbiology.com/posts/nls_modelFitting.html#quadratic-polynomial-function" rel="nofollow" target="_blank">this link</a> for an example of fitting.</p>
</section>
</section>
<section id="concaveconvex-curves-no-inflection-points" class="level1">
<h1>Concave/Convex curves (no inflection points)</h1>
<section id="exponential-function" class="level2">
<h2 class="anchored" data-anchor-id="exponential-function">Exponential function</h2>
<p>The most common parameterisation of an exponential function is:</p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20a%20e%5E%7Bk%20X%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(3)%20"></p>
<p>Depending on the sign of <img src="https://latex.codecogs.com/png.latex?k">, Eq. 3 describes a concave-up monotonically increasing shape (exponential growth; <img src="https://latex.codecogs.com/png.latex?k%20%3E%200">) or a concave-up monotonically decreasing shape (exponential decay; <img src="https://latex.codecogs.com/png.latex?k%20%3C%200">).</p>
<p>The parameter <img src="https://latex.codecogs.com/png.latex?a"> represents the value of <img src="https://latex.codecogs.com/png.latex?Y"> when <img src="https://latex.codecogs.com/png.latex?X%20=%200">, whereas the meaning of <img src="https://latex.codecogs.com/png.latex?k"> can be understood by considering the first derivative:</p>
<div class="cell">
<pre>D(expression(a * exp(k * X)), &quot;X&quot;)</pre>
<div class="cell-output cell-output-stdout">
<pre>a * (exp(k * X) * k)</pre>
</div>
</div>
<p>In algebraic terms, it is:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cfrac%7BdY%7D%7BdX%7D%20=%20k%20%5C,%20a%20%5C,%20e%5E%7Bk%20%5C,%20X%7D%20=%20k%20%5C,%20Y"></p>
<p>and thus:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cfrac%7BdY%7D%7BdX%7D%20%5Cfrac%7B1%7D%7BY%7D%20=%20k"></p>
<p>Therefore, <img src="https://latex.codecogs.com/png.latex?k"> represents the relative rate of change (increase/decrease), throughout the domain, which is often known in growth analysis as the Relative Growth Rate (RGR).</p>
<p>Other equivalent parameterisations are:</p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20e%5E%7Bd%20+%20k%20X%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(4)"></p>
<p>and:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20%20%5C,%20b%5EX%20%5Cquad%20%5Cquad%20%5Cquad%20(5)"></p>
<p>Equations 3-5 are equivalent, as can be shown by setting <img src="https://latex.codecogs.com/png.latex?b%20=%20e%5Ek"> and <img src="https://latex.codecogs.com/png.latex?a%20=%20e%5Ed">:</p>
<p><img src="https://latex.codecogs.com/png.latex?a%20%5C,%20b%5EX%20%20=%20e%20%5E%20d%20%20(e%5E%7BkX%7D%20)%20=%20%20a%20%20%5C,%20e%5E%7BkX%7D"></p>
<p>Another, slightly different, parameterisation is commonly used in bioassay studies, mainly to describe exponential decay processes:</p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20d%20%5Cexp(-x/e)%20%5Cquad%20%5Cquad%20%5Cquad%20(6)"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?d"> corresponds to <img src="https://latex.codecogs.com/png.latex?a"> in the previous models and <img src="https://latex.codecogs.com/png.latex?e%20=%20-%201/k">.</p>
<p>For all the exponential decay equations presented above, <img src="https://latex.codecogs.com/png.latex?Y%20%5Crightarrow%200"> as <img src="https://latex.codecogs.com/png.latex?X%20%5Crightarrow%20%5Cinfty">. A lower asymptote, <img src="https://latex.codecogs.com/png.latex?c%20%5Cneq%200">, can be incorporated into Eq. 6 to account for situations in which the response does not approach zero as the predictor tends to infinity:</p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20c%20+%20(d%20-c)%20%5Cexp(-x/e)%20%5Cquad%20%5Cquad%20%5Cquad%20(7)"></p>
<p>Exponential functions are often used to describe the growth of populations under non-limiting environmental conditions or the degradation of xenobiotics in the environment (first-order degradation kinetics). In both cases, <img src="https://latex.codecogs.com/png.latex?X"> represents time and is therefore restricted to non-negative values, while <img src="https://latex.codecogs.com/png.latex?b"> (or, equivalently, <img src="https://latex.codecogs.com/png.latex?k">) must be different from zero. Check the post <a href="https://www.statforbiology.com/posts/nls_modelFitting.html#exponential-function" rel="nofollow" target="_blank">at this link</a> for an example of fitting.</p>
</section>
<section id="asymptotic-function" class="level2">
<h2 class="anchored" data-anchor-id="asymptotic-function">Asymptotic function</h2>
<p>This function appears in several different parameterisations and is also known as the <em>monomolecular growth</em> function, the <em>Mitscherlich law</em>, or the <em>von Bertalanffy law</em>. Owing to its biological interpretation, the most widely used parameterisation is:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20-%20(a%20-%20b)%20%5C,%20%5Cexp%20(-%20m%20X)%20%5Cquad%20%5Cquad%20%5Cquad%20(8)"></p>
<p>It describes a monotonically increasing, concave-down curve approaching a horizontal asymptote as <img src="https://latex.codecogs.com/png.latex?X"> tends to infinity. The parameter <img src="https://latex.codecogs.com/png.latex?a"> represents the maximum attainable value of <img src="https://latex.codecogs.com/png.latex?Y"> (the plateau), while <img src="https://latex.codecogs.com/png.latex?b"> is the value of <img src="https://latex.codecogs.com/png.latex?Y"> when <img src="https://latex.codecogs.com/png.latex?X%20=%200"> (the initial value). The parameter <img src="https://latex.codecogs.com/png.latex?m"> is proportional to the rate at which the response approaches the plateau. Indeed, the first derivative is</p>
<div class="cell">
<pre>D(expression(a - (a - b) * exp (- m * X)), &quot;X&quot;)</pre>
<div class="cell-output cell-output-stdout">
<pre>(a - b) * (exp(-m * X) * m)</pre>
</div>
</div>
<p>Considering Eq.8, we can write:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cfrac%7BdY%7D%7BdX%7D%20=%20m%20%5C,%20(a%20-%20Y)"></p>
<p>and then:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cfrac%7BdY%7D%7BdX%7D%20%5Cfrac%7B1%7D%7BY%7D%20=%20m%20%5C,%20%5Cfrac%7B(a%20-%20Y)%7D%7BY%7D"></p>
<p>The previous expression shows that the relative rate of change in the response (the RGR in growth analysis) is not constant, as it is for the exponential function. Instead, it depends on the attained value of <img src="https://latex.codecogs.com/png.latex?Y">. In particular, the RGR is greatest at the beginning of the process, when <img src="https://latex.codecogs.com/png.latex?Y"> is smallest, and gradually approaches zero as <img src="https://latex.codecogs.com/png.latex?Y"> approaches the plateau <img src="https://latex.codecogs.com/png.latex?a">.</p>
<p>Another closely related parameterisation is often encountered, in which <img src="https://latex.codecogs.com/png.latex?a"> is replaced by <img src="https://latex.codecogs.com/png.latex?d">, <img src="https://latex.codecogs.com/png.latex?b"> by <img src="https://latex.codecogs.com/png.latex?c">, and <img src="https://latex.codecogs.com/png.latex?m"> by <img src="https://latex.codecogs.com/png.latex?e%20=%201/m">. Some simple algebraic manipulations are also introduced to make the model consistent with the parameterisation commonly adopted for biological assay models:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20(d%20-%20c)%20%5C,%20%5Cleft%5B1%20-%20%5Cexp%20%5Cleft(-%20%5Cfrac%7BX%7D%7Be%7D%20%5Cright)%20%5Cright%5D%20%5Cquad%20%5Cquad%20%5Cquad%20(9)"></p>
<p>In some applications, <img src="https://latex.codecogs.com/png.latex?m"> is reparameterised through its logarithm to facilitate model fitting:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20-%20(a%20-%20b)%20%5C,%20%5Cexp%20(-%20log(f)%20X)%20%5Cquad%20%5Cquad%20%5Cquad%20(10)"></p>
<p>For all these equations, setting <img src="https://latex.codecogs.com/png.latex?b%20=%200"> (or equivalently <img src="https://latex.codecogs.com/png.latex?c%20=%200">) yields a curve passing through the origin. In this case, the most common parameterisation is:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20%5Cleft%5B%201-%20%5Cexp%20(-%20m%20X)%20%5Cright%5D%20%5Cquad%20%5Cquad%20%5Cquad%20(11)"></p>
<p>which is known as the <em>negative exponential function</em>.</p>
<p>The asymptotic function is widely used in biology, not only for growth analysis but also, for example, in weed competition studies. The negative exponential function has also been used to model the absorbed Photosynthetically Active Radiation (<img src="https://latex.codecogs.com/png.latex?Y%20=%20PAR_a">) as a function of leaf area index (<img src="https://latex.codecogs.com/png.latex?X%20=%20LAI">). In this context, <img src="https://latex.codecogs.com/png.latex?a"> represents the incident PAR (<img src="https://latex.codecogs.com/png.latex?a%20=%20PAR_i">), while <img src="https://latex.codecogs.com/png.latex?m"> is the light extinction coefficient. Check the post <a href="https://www.statforbiology.com/posts/nls_modelFitting.html#asymptotic-function" rel="nofollow" target="_blank">at this link</a> for an example of fitting.</p>
</section>
<section id="power-function" class="level2">
<h2 class="anchored" data-anchor-id="power-function">Power function</h2>
<p>The power function is also known as <em>Freundlich function</em> or <em>allometric function</em>. The most common parameterisation is:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20%5C,%20X%5Eb%20%5Cquad%20%5Cquad%20%5Cquad%20(12)"></p>
<p>Its shape is highly flexible and is determined by the value of the parameter <img src="https://latex.codecogs.com/png.latex?b"> (see Figure 1). When <img src="https://latex.codecogs.com/png.latex?0%20%3C%20b%20%3C%201">, the response <img src="https://latex.codecogs.com/png.latex?Y"> increases with <img src="https://latex.codecogs.com/png.latex?X"> and the curve is concave down. When <img src="https://latex.codecogs.com/png.latex?b%20%3C%200">, <img src="https://latex.codecogs.com/png.latex?Y"> decreases as <img src="https://latex.codecogs.com/png.latex?X"> increases and the curve is concave up. Finally, when <img src="https://latex.codecogs.com/png.latex?b%20%3E%201">, <img src="https://latex.codecogs.com/png.latex?Y"> increases with <img src="https://latex.codecogs.com/png.latex?X"> and the curve is concave up. These three cases are illustrated in Figure 1 using different colours. The function is defined only for <img src="https://latex.codecogs.com/png.latex?X%20%3E%200"> and has no horizontal asymptote as <img src="https://latex.codecogs.com/png.latex?X%20%5Crightarrow%20%5Cinfty">.</p>
<p>The biological interpretation of the parameters <img src="https://latex.codecogs.com/png.latex?a"> and <img src="https://latex.codecogs.com/png.latex?b"> is not straightforward. Both influence the slope of the curve, as can be seen by examining the first derivative:</p>
<div class="cell">
<pre>D(expression(a * X^b), &quot;X&quot;)</pre>
<div class="cell-output cell-output-stdout">
<pre>a * (X^(b - 1) * b)</pre>
</div>
</div>
<p>The power function is mathematically equivalent to an exponential function of <img src="https://latex.codecogs.com/png.latex?%5Clog(X)">, since:</p>
<p><img src="https://latex.codecogs.com/png.latex?a%20%5C,X%5Eb%20=%20a%20%5C,%20e%5E%7B%5Clog(%20X%5Eb%20)%7D%20=%20a%20%5C,%20e%5E%7Bb%20%5C,%20%5Clog(X)%7D"></p>
<p>The power function (named as the Freundlich equation) is widely used in agricultural chemistry, for example to model the sorption of xenobiotics in soil. It is also used to describe the relationship between the number of plant species and the sampled area (the species–area relationship). Check the post <a href="https://www.statforbiology.com/posts/nls_modelFitting.html#power-function" rel="nofollow" target="_blank">at this link</a> for an example of fitting.</p>
</section>
<section id="logarithmic-function" class="level2">
<h2 class="anchored" data-anchor-id="logarithmic-function">Logarithmic function</h2>
<p>This function is linear in <img src="https://latex.codecogs.com/png.latex?%5Clog(X)">:</p>
<p><img src="https://latex.codecogs.com/png.latex?y%20=%20a%20+%20b%20%5C,%20%5Clog(X)%20%5Cquad%20%5Cquad%20%5Cquad%20(13)"></p>
<p>Because of the logarithmic transformation, the function is only defined for <img src="https://latex.codecogs.com/png.latex?X%20%3E%200">. The parameter <img src="https://latex.codecogs.com/png.latex?b"> determines the shape of the curve. When <img src="https://latex.codecogs.com/png.latex?b%20%3E%200">, the response <img src="https://latex.codecogs.com/png.latex?Y"> increases with <img src="https://latex.codecogs.com/png.latex?X"> and the curve is concave down. Conversely, when <img src="https://latex.codecogs.com/png.latex?b%20%3C%200">, <img src="https://latex.codecogs.com/png.latex?Y"> decreases as <img src="https://latex.codecogs.com/png.latex?X"> increases and the curve is concave up, as shown in Figure 1.</p>
<p>The interpretation of the parameters is fairly straightforward. The parameter <img src="https://latex.codecogs.com/png.latex?a"> is the value of the response when <img src="https://latex.codecogs.com/png.latex?X%20=%201">. Changing <img src="https://latex.codecogs.com/png.latex?a"> while keeping <img src="https://latex.codecogs.com/png.latex?b"> constant simply shifts the curve vertically without altering its shape, so that the difference between any two curves remains constant for every value of <img src="https://latex.codecogs.com/png.latex?X"> (Fig. 2).</p>
<p>The parameter <img src="https://latex.codecogs.com/png.latex?b"> controls the slope of the curve and, more specifically, it is equal to the slope at <img src="https://latex.codecogs.com/png.latex?X%20=%201">, as can be seen from the expression for the first derivative:</p>
<div class="cell">
<pre>D(expression(a + b*log(X)), &quot;X&quot;)</pre>
<div class="cell-output cell-output-stdout">
<pre>b * (1/X)</pre>
</div>
</div>
<p>Changing <img src="https://latex.codecogs.com/png.latex?b"> while keeping <img src="https://latex.codecogs.com/png.latex?a"> constant produces curves that all intersect at <img src="https://latex.codecogs.com/png.latex?X%20=%201"> (Fig. 2).</p>
<div class="cell">
<div class="cell-output-display">
<div id="fig-2" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://i0.wp.com/www.statforbiology.com/posts/nls_usefulEquations_files/figure-html/fig-2-1.png?w=578&#038;ssl=1" class="img-fluid figure-img" style="width:75.0%" data-recalc-dims="1">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure 2: Effects of changing parameter values on the shape of logarithmic curves. The parameter <img src="https://latex.codecogs.com/png.latex?a"> is 1 for the red curves and 3 for the black curves, while <img src="https://latex.codecogs.com/png.latex?b"> is 1 for the solid lines (-1 on the right panel) and 0.5 for the dotted lines (-0.5 in the right panel)
</figcaption>
</figure>
</div>
</div>
</div>
<p>In biology, logarithmic functions are used, for example, to describe species–area relationships in ecology, enzyme kinetics in biochemistry, and sensory perception in neurobiology. Check the post <a href="https://www.statforbiology.com/posts/nls_modelFitting.html#logarithmic-function" rel="nofollow" target="_blank">at this link</a> for an example of fitting.</p>
</section>
<section id="rectangular-hyperbola" class="level2">
<h2 class="anchored" data-anchor-id="rectangular-hyperbola">Rectangular hyperbola</h2>
<p>The rectangular hyperbola is commonly known as the Michaelis-Menten function and is usually parameterised as</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20%5Cfrac%7Ba%20%5C,%20X%7D%20%7Bb%20+%20X%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(14)"></p>
<p>The curve is monotonically increasing and concave down, approaching the horizontal asymptote (plateau) <img src="https://latex.codecogs.com/png.latex?a">. It passes through the origin of the axes (<img src="https://latex.codecogs.com/png.latex?Y%20=%200"> when <img src="https://latex.codecogs.com/png.latex?X%20=%200">). The parameter <img src="https://latex.codecogs.com/png.latex?b"> is the value of <img src="https://latex.codecogs.com/png.latex?X"> that produces a response equal to <img src="https://latex.codecogs.com/png.latex?a/2">. Indeed,</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cfrac%7Ba%7D%7B2%7D%20=%20%5Cfrac%7Ba%20%5C,X_%7B50%7D%20%7D%20%7Bb%20+%20X_%7B50%7D%20%7D"></p>
<p>which is readily solved to obtain <img src="https://latex.codecogs.com/png.latex?X_%7B50%7D%20=%20b">.</p>
<p>The first derivative is:</p>
<div class="cell">
<pre>D(expression( (a*X) / (b + X) ), &quot;X&quot;)</pre>
<div class="cell-output cell-output-stdout">
<pre>a/(b + X) - (a * X)/(b + X)^2</pre>
</div>
</div>
<p>From this expression, we can see that the initial slope (at <img src="https://latex.codecogs.com/png.latex?X%20=%200">) is <img src="https://latex.codecogs.com/png.latex?i%20=%20a/b">.</p>
<p>Equation 14 is not defined for <img src="https://latex.codecogs.com/png.latex?X%20=%20-b"> and has no biological meaning for <img src="https://latex.codecogs.com/png.latex?X%20%3C%20-b">. In most biological applications, however, both <img src="https://latex.codecogs.com/png.latex?X"> and <img src="https://latex.codecogs.com/png.latex?b"> are positive.</p>
<p>An equivalent parameterisation is:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20%5Cfrac%7Ba%20%5C,%20X%7D%20%7Bb%20+%20X%7D%20=%20%5Cfrac%7Ba%7D%7B%20%5Cfrac%7Bb%7D%7BX%7D%20+%20%5Cfrac%7BX%7D%7BX%7D%7D%20=%20%5Cfrac%7Ba%7D%7B1%20+%20%5Cfrac%7Bb%7D%7BX%7D%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(15)"></p>
<p>In this form, the parameters <img src="https://latex.codecogs.com/png.latex?a"> and <img src="https://latex.codecogs.com/png.latex?b"> are often replaced by <img src="https://latex.codecogs.com/png.latex?d"> and <img src="https://latex.codecogs.com/png.latex?e">, respectively. Although the response is not defined for <img src="https://latex.codecogs.com/png.latex?X%20=%200">, it tends to zero as <img src="https://latex.codecogs.com/png.latex?X%20%5Crightarrow%200">.</p>
<p>Another common parameterisation includes the initial slope <img src="https://latex.codecogs.com/png.latex?i"> as an explicit parameter because of its biological relevance. This is obtained by dividing both the numerator and denominator by <img src="https://latex.codecogs.com/png.latex?b"> and noting that <img src="https://latex.codecogs.com/png.latex?i%20=%20a/b">, so that <img src="https://latex.codecogs.com/png.latex?b%20=%20a/i">:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20%5Cfrac%7Ba%20%5C,%20X%7D%20%7Bb%20+%20X%7D%20=%20%5Cfrac%7B%20%5Cfrac%7Ba%7D%7Bb%7D%20%5C,%20X%7D%20%7B%5Cfrac%7Bb%7D%7Bb%7D%20+%20%5Cfrac%7BX%7D%7Bb%7D%7D%20=%20%5Cfrac%7Bi%20%5C,%20X%7D%7B1%20+%20%5Cfrac%7Bi%20%5C,%20X%20%7D%7Ba%7D%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(16)"></p>
<p>The Michaelis-Menten function is widely used in pesticide chemistry, enzyme kinetics (Eq. 14), biological assay models (Eq. 15), and weed competition studies, where it is used to describe crop yield loss as a function of weed density (Eq. 16). An example of fitting is shown in another post, <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html#rectangular-hyperbola" rel="nofollow" target="_blank">at this link</a>.</p>
</section>
</section>
<section id="sigmoidal-function" class="level1">
<h1>Sigmoidal functions</h1>
<p>Sigmoidal functions are S-shaped, with two horizontal asymptotes (a lower and an upper asymptote) and an inflection point. They can be parameterised in countless ways, which may be confusing when selecting the most appropriate model for a particular biological process. In this post, I will use the parameterisations proposed in Ritz et al (2019), which is very consistent and puts all the curves on the same ground. Furthermore, the fitting properties are good, which contribute to good convergence and reliable estimation.</p>
<p>For the sake of simplicity, it is useful to recognise that most sigmoidal models belong to one of three basic families, which differ only in the position of the inflection point relative to the two asymptotes:</p>
<ol type="1">
<li><strong>Logistic</strong>: the ordinate of the inflection point lies halfway between the lower and upper asymptotes; consequently, the S-shape is symmetric (the concave-up and the concave-down portions ‘mirror’ each other).</li>
<li><strong>Gompertz</strong>: the ordinate of the inflection point lies closer to the lower asymptote, and, thus, the concave-up portions is ‘shorter’ than the concave-down portion.</li>
<li><strong>Modified Gompertz</strong>: the ordinate of the inflection point lies closer to the upper asymptote, and, thus, the concave-up portion is ‘longer’ than than the concave-down portion.</li>
</ol>
<p>Each of these three equations can describe either increasing or decreasing responses, depending on the sign of one of the model parameters (see below). Their different shapes are compared side by side in Fig. 3.</p>
<div class="cell">
<div class="cell-output-display">
<div id="fig-3" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://i1.wp.com/www.statforbiology.com/posts/nls_usefulEquations_files/figure-html/fig-3-1.png?w=450&#038;ssl=1" class="img-fluid figure-img"  data-recalc-dims="1">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure 3: The different shapes of sigmoidal curves based on x: logistic (red lines), Gompertz (blue lines) and modified Gompertz (green lines).
</figcaption>
</figure>
</div>
</div>
</div>
<p>Each of these three families (logistic, Gompertz and modified Gompertz) can be transformed by replacing <img src="https://latex.codecogs.com/png.latex?X"> with <img src="https://latex.codecogs.com/png.latex?%5Clog(X)">, giving raise to three corresponding families:</p>
<ol type="1">
<li><strong>Log-logistic</strong></li>
<li><strong>Type-I Weibull</strong></li>
<li><strong>Type-II Weibull</strong></li>
</ol>
<p>Like their linear-scale counterparts, these three families can describe either increasing or decreasing responses, depending on the sign of the same model parameter (see below). In the end, we have twelve different sigmoidal functions to choose from. The choice among them depends primarily on the expected symmetry of the response and on whether the predictor is more naturally interpreted on a linear or logarithmic scale.</p>
<p>Thanks to their versatility, sigmoidal functions have been used for an uncountable number of biological applications. Just to mention a few examples in agriculture, I would like to cite plant growth, dose-response curves in biological assays and the time-course of seed germination. For some examples, take a look at my post <a href="https://www.statforbiology.com/posts/nls_modelFitting.html#sigmoidal-function" rel="nofollow" target="_blank">at this link</a>.</p>
<section id="logistic-function" class="level2">
<h2 class="anchored" data-anchor-id="logistic-function">Logistic function</h2>
<p>The logistic curve is derived from the cumulative logistic distribution function. It is symmetric about its inflection point and can be parameterised as:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20%5Cfrac%7Bd%20-%20c%7D%7B1%20+%20exp(-%20b%20(X%20-%20e))%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(17)"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?d"> is the upper asymptote, <img src="https://latex.codecogs.com/png.latex?c"> is the lower asymptote, <img src="https://latex.codecogs.com/png.latex?e"> is the value of <img src="https://latex.codecogs.com/png.latex?X"> at the inflection point, and <img src="https://latex.codecogs.com/png.latex?b"> is proportional to the slope at the inflection point. Because the curve is symmetric, <img src="https://latex.codecogs.com/png.latex?e"> also represents the value of <img src="https://latex.codecogs.com/png.latex?X"> that produces a response halfway between <img src="https://latex.codecogs.com/png.latex?d"> and <img src="https://latex.codecogs.com/png.latex?c"> (commonly referred to as the ED50 in biological assays). The parameter <img src="https://latex.codecogs.com/png.latex?b"> may be either positive or negative and, consequently, the response may either increase or decrease as <img src="https://latex.codecogs.com/png.latex?X"> increases.</p>
<p>This equation is known as the four-parameter logistic model. If appropriate, constraints can be imposed on the parameter values. For example, <img src="https://latex.codecogs.com/png.latex?c"> may be fixed at 0, yielding the three-parameter logistic model. If, in addition, <img src="https://latex.codecogs.com/png.latex?d"> is fixed at 1, the model reduces to the two-parameter logistic model.</p>
</section>
<section id="gompertz-function" class="level2">
<h2 class="anchored" data-anchor-id="gompertz-function">Gompertz function</h2>
<p>The Gompertz curve can be parameterised in many different ways. I prefer a parameterisation that closely resembles that of the logistic function:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20(d%20-%20c)%20%5Cexp%20%5Cleft%5C%7B-%20%5Cexp%20%5Cleft%5B%20-%20b%20%5C,%20(X%20-%20e)%20%5Cright%5D%20%5Cright%5C%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(18)"></p>
<p>Unlike the logistic function, the Gompertz curve is not symmetric about its inflection point. It exhibits a longer lag phase at the beginning, followed by a progressively steeper increase before gradually approaching the upper asymptote. The parameters have essentially the same interpretation as those of the logistic function, except that <img src="https://latex.codecogs.com/png.latex?e">, the abscissa of the inflection point, does not correspond to the value of <img src="https://latex.codecogs.com/png.latex?X"> producing a response halfway between <img src="https://latex.codecogs.com/png.latex?c"> and <img src="https://latex.codecogs.com/png.latex?d">.</p>
<p>As with the logistic function, four-, three-, and two-parameter Gompertz models can be obtained by constraining one or both asymptotes.</p>
</section>
<section id="modified-gompertz-function" class="level2">
<h2 class="anchored" data-anchor-id="modified-gompertz-function">Modified Gompertz function</h2>
<p>We have seen that the logistic curve is symmetric about its inflection point, whereas the Gompertz curve exhibits a longer lag phase at the beginning, followed by a progressively steeper increase. A different asymmetric pattern can be obtained by modifying the Gompertz function as follows:</p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20c%20+%20(d%20-%20c)%20%5Cleft%5C%7B%201%20-%20%5Cexp%20%5Cleft%5C%7B-%20%5Cexp%20%5Cleft%5B%20b%20%5C,%20(X%20-%20e)%20%5Cright%5D%20%5Cright%5C%7D%20%5Cright%5C%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(19)"></p>
<p>The resulting curve increases rapidly at the beginning but gradually slows down as it approaches the upper asymptote. As with the logistic and Gompertz functions, one or both asymptotes can be constrained (<img src="https://latex.codecogs.com/png.latex?d%20=%201"> and/or <img src="https://latex.codecogs.com/png.latex?c%20=%200">), giving rise to four-, three-, and two-parameter versions of the modified Gompertz model.</p>
</section>
<section id="log-logistic-function" class="level2">
<h2 class="anchored" data-anchor-id="log-logistic-function">Log-logistic function</h2>
<p>The log-logistic curve is symmetric with respect to <img src="https://latex.codecogs.com/png.latex?%5Clog(X)">. A log-normal curve has a very similar shape, although it is used much less frequently. In biological assays (and also in germination studies), the log-logistic function is commonly parameterised as</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20%5Cfrac%7Bd%20-%20c%7D%7B1%20+%20%5Cexp%20%5Cleft%5C%7B%20-%20b%20%5Cleft%5B%20%5Clog(X)%20-%20%5Clog(e)%20%5Cright%5D%20%5Cright%5C%7D%20%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(20)"></p>
<p>The parameters have the same interpretation as in the logistic function. In particular, <img src="https://latex.codecogs.com/png.latex?e"> represents the value of <img src="https://latex.codecogs.com/png.latex?X"> that produces a response halfway between <img src="https://latex.codecogs.com/png.latex?c"> and <img src="https://latex.codecogs.com/png.latex?d"> (the ED50). It is easy to show that the above equation is equivalent to</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20%5Cfrac%7Bd%20-%20c%7D%7B1%20+%20%5Cleft(%20%5Cfrac%7BX%7D%7Be%7D%20%5Cright)%5E%7B-b%7D%7D"></p>
<p>Like the logistic function, the log-logistic model can be fitted in four-, three-, or two-parameter versions by constraining one or both asymptotes. It is widely used to describe dose-response relationships in biological assays, seed germination, and crop growth.</p>
</section>
<section id="weibull-function-type-1" class="level2">
<h2 class="anchored" data-anchor-id="weibull-function-type-1">Weibull function (type 1)</h2>
<p>The Type I Weibull function is the logarithmic counterpart of the Gompertz function, being defined on <img src="https://latex.codecogs.com/png.latex?%5Clog(X)"> rather than on <img src="https://latex.codecogs.com/png.latex?X">. It is parameterised as</p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20c%20+%20(d%20-%20c)%20%5Cexp%20%5Cleft%5C%7B-%20%5Cexp%20%5Cleft%5B%20-%20b%20%5C,%20(%5Clog(X)%20-%20%5Clog(e))%20%5Cright%5D%20%5Cright%5C%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(21)"></p>
<p>The parameters have essentially the same interpretation as those of the other sigmoidal functions presented above. In particular, <img src="https://latex.codecogs.com/png.latex?c"> and <img src="https://latex.codecogs.com/png.latex?d"> are the lower and upper asymptotes, respectively, while <img src="https://latex.codecogs.com/png.latex?e"> is the value of <img src="https://latex.codecogs.com/png.latex?X"> corresponding to the inflection point. Unlike the log-logistic function, however, <img src="https://latex.codecogs.com/png.latex?e"> does not correspond to the ED50.</p>
</section>
<section id="weibull-function-type-2" class="level2">
<h2 class="anchored" data-anchor-id="weibull-function-type-2">Weibull function (type 2)</h2>
<p>The Type II Weibull function is closely related to the Type I Weibull function, but it describes a different type of asymmetry, analogous to that of the modified Gompertz function:</p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20c%20+%20(d%20-%20c)%20%5Cleft%5C%7B%201%20-%20%5Cexp%20%5Cleft%5C%7B-%20%5Cexp%20%5Cleft%5B%20b%20%5C,%20(%5Clog(X)%20-%20%5Clog(e))%20%5Cright%5D%20%5Cright%5C%7D%20%5Cright%5C%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(22)"></p>
<p>The parameters have the same interpretation as those of the Type I Weibull function. In particular, <img src="https://latex.codecogs.com/png.latex?c"> and <img src="https://latex.codecogs.com/png.latex?d"> are the lower and upper asymptotes, respectively, while <img src="https://latex.codecogs.com/png.latex?e"> is the value of <img src="https://latex.codecogs.com/png.latex?X"> at the inflection point. As with the Type I Weibull function, <img src="https://latex.codecogs.com/png.latex?e"> does not correspond to the ED50. One or both asymptotes may be constrained, giving rise to four-, three-, and two-parameter versions of the model.</p>
</section>
<section id="another-flexible-sigmoid" class="level2">
<h2 class="anchored" data-anchor-id="another-flexible-sigmoid">Another ‘flexible’ sigmoid</h2>
<p>I would also like to mention another sigmoidal function that has been widely used in biology because of its supposed flexibility: the <em>Richards</em> function:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20%5Cfrac%7Bd%20-%20c%7D%7B%5Cleft%5B1%20+%20exp(-%20b%20(X%20-%20e))%5Cright%5D%5E%7B1/f%7D%7D"></p>
<p>In this model, the degree of asymmetry is controlled by the parameter <img src="https://latex.codecogs.com/png.latex?f">. When <img src="https://latex.codecogs.com/png.latex?f%20=%201">, the function reduces to the logistic model, whereas, as <img src="https://latex.codecogs.com/png.latex?f"> decreases below 1, the curve progressively resembles a Gompertz function. Figure 4 illustrates the different shapes obtained for different values of <img src="https://latex.codecogs.com/png.latex?f">.</p>
<p>Despite this apparent flexibility, the Richards function has poor statistical properties for parameter estimation. In particular, the additional parameter often causes strong correlations among the estimates, making the fitting process unstable and the parameter estimates difficult to interpret. Ratkowsky (1990) described it as having <em>“more undesirable nonlinear regression behaviour than almost any nonlinear regression model in common use.”</em> For these reasons, the Richards function will not be considered further in this blog.</p>
<div class="cell">
<div class="cell-output-display">
<div id="fig-4" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-4-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://i0.wp.com/www.statforbiology.com/posts/nls_usefulEquations_files/figure-html/fig-4-1.png?w=450&#038;ssl=1" class="img-fluid figure-img"  data-recalc-dims="1">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-4-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure 4: The different shapes of the Richard’s function, based on the <img src="https://latex.codecogs.com/png.latex?f"> parameter: <img src="https://latex.codecogs.com/png.latex?f%20=%201"> (black line), <img src="https://latex.codecogs.com/png.latex?f%20=%200.5"> (blue line) and <img src="https://latex.codecogs.com/png.latex?f%20=%201.5"> (red line)
</figcaption>
</figure>
</div>
</div>
</div>
</section>
</section>
<section id="maxima-fun" class="level1">
<h1>Curves with maxima/minima</h1>
<p>It is sometimes necessary to describe phenomena where the <img src="https://latex.codecogs.com/png.latex?Y"> variable reaches a maximum value at a certain level of the <img src="https://latex.codecogs.com/png.latex?X"> variable, and drops afterwords. For example, growth or germination rates are higher at optimal temperature levels and lower at supra-optimal or sub-optimal temperature levels. Another example relates to bioassays: in some cases, low doses of toxic substances induce a stimulation of growth (hormesis), which needs to be described by an appropriate model. The second order (and higher order) polynomial funcion we have seen earlier is capable of accounting for maxima/minima, but there are a few other interesting functions that may turn out useful in some circumstances.</p>
<section id="brain-function" class="level2">
<h2 class="anchored" data-anchor-id="brain-function">Peaked sigmoidal function</h2>
<p>The log-logistic decreasing curve can be modified to account for possible hormetic effects at low doses, by combining mathematical switching functions (Schabenberger and Pierce, 2002; pag. 275). The most widespread parameterisation, that was originally devised by Brain and Cousens (<em>Brain, P., Cousens, R., 1989. An equation to describe dose responses where there is stimulation of growth at low doses. Weed Research 29, 93–96</em>) in a slightly different form, is:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20%5Cfrac%7Bd%20-%20c%20+%20f%20%5C,%20X%7D%7B1%20+%20%5Cexp%20%5Cleft%5C%7B%20-%20b%20%5Cleft%5B%20%5Clog(X)%20-%20%5Clog(e)%20%5Cright%5D%20%5Cright%5C%7D%20%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(23)"></p>
<p>The parameters have the same interpretation as in the log-logistic curves, but <img src="https://latex.codecogs.com/png.latex?e"> does not represent the response half-way between the lower and higher asymptote and <img src="https://latex.codecogs.com/png.latex?f%20%3E%200"> represents the size of the hormetic effect, which increases as <img src="https://latex.codecogs.com/png.latex?f"> increases, while <img src="https://latex.codecogs.com/png.latex?f%20=%200"> corresponds to the situation of no hormesis (and the function reduces to a log-logistic.</p>
</section>
<section id="bragg-function" class="level2">
<h2 class="anchored" data-anchor-id="bragg-function">Bragg function</h2>
<p>This function is connected to the normal (Gaussian) distribution and has a symmetric shape with a maximum equal to <img src="https://latex.codecogs.com/png.latex?d">, that is reached when <img src="https://latex.codecogs.com/png.latex?X%20=%20e"> and two inflection points. In this model, <img src="https://latex.codecogs.com/png.latex?b"> relates to the slope at the inflection points; the response <img src="https://latex.codecogs.com/png.latex?Y"> approaches 0 when <img src="https://latex.codecogs.com/png.latex?X"> approaches <img src="https://latex.codecogs.com/png.latex?%5Cpm%20%5Cinfty">:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20d%20%5C,%20%5Cexp%20%5Cleft%5B%20-%20b%20(X%20-%20e)%5E2%20%5Cright%5D%20%5Cquad%20%5Cquad%20%5Cquad%20(24)"></p>
<p>If we would like to have lower asymptotes different from 0, we should add the parameter <img src="https://latex.codecogs.com/png.latex?c">, as follows:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20(d%20-%20c)%20%5C,%20%5Cexp%20%5Cleft%5B%20-%20b%20(X%20-%20e)%5E2%20%5Cright%5D%20%5Cquad%20%5Cquad%20%5Cquad%20(24a)"></p>
<p>The two Bragg functions have proven useful in applications relating to the science of carbon materials.</p>
</section>
<section id="lorentz-function" class="level2">
<h2 class="anchored" data-anchor-id="lorentz-function">Lorentz function</h2>
<p>The Lorentz function is similar to the Bragg function, although it has worse statistical properties (Ratkowsky, 1990). The equation is:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20%5Cfrac%7Bd%7D%20%7B%201%20+%20b%20(X%20-%20e)%5E2%20%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(25)"></p>
<p>We can also allow for lower asymptotes different from 0, by adding a further parameter:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20%5Cfrac%7Bd%20-%20c%7D%20%7B%201%20+%20b%20(X%20-%20e)%5E2%20%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(25a)"></p>
</section>
<section id="beta-function" class="level2">
<h2 class="anchored" data-anchor-id="beta-function">Beta function</h2>
<p>The beta function derives from the beta density function and it has been adapted to describe phenomena taking place only within a minimum and a maximum threshold value (threshold model). One typical example is seed germination, where the germination rate (GR, i.e. the inverse of germination time) is 0 below the base temperature level and above the cutoff temperature level. Between these two extremes, the GR increases with temperature up to a maximum level, that is reached at the optimal temperature level.</p>
<p>The equation is:</p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20d%20%5C,%5Cleft%5C%7B%20%20%5Cleft(%20%5Cfrac%7BX%20-%20X_b%7D%7BX_o%20-%20X_b%7D%20%5Cright)%20%5Cleft(%20%5Cfrac%7BX_c%20-%20X%7D%7BX_c%20-%20X_o%7D%20%5Cright)%20%5E%20%7B%5Cfrac%7BX_c%20-%20X_o%7D%7BX_o%20-%20X_b%7D%7D%20%5Cright%5C%7D%5Eb%20%5Cquad%20%5Cquad%20%5Cquad%20(26)"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?d"> is the maximum level for the expected response <img src="https://latex.codecogs.com/png.latex?Y">, <img src="https://latex.codecogs.com/png.latex?X_b"> and <img src="https://latex.codecogs.com/png.latex?X_c"> are, respectively, the minumum and maximum threshold levels, <img src="https://latex.codecogs.com/png.latex?X_o"> is the abscissa at the maximum expected response level and <img src="https://latex.codecogs.com/png.latex?b"> is a shape parameter. The above function is only defined for <img src="https://latex.codecogs.com/png.latex?X_b%20%3C%20X%20%3C%20X_c"> and it returns 0 elsewhere.</p>
</section>
</section>
<section id="conclusions" class="level1">
<h1>Conclusions</h1>
<p>Here we are; I have discussed more almost 30 functions, which are commonly used to model biological processes. These functions can be found in several other different parameterisations and I suggest you read the book chapter by Miguez et al. (2018), for other interesting information.</p>
<p>Thanks for reading! And … don’t forget to check out my new book!</p>
<p>Prof. Andrea Onofri<br>
Department of Agricultural, Food and Environmental Sciences<br>
University of Perugia (Italy)<br>
Send comments to: <a href="mailto:andrea.onofri@unipg.it" rel="nofollow" target="_blank">andrea.onofri@unipg.it</a></p>
<p><a href="https://www.awin1.com/cread.php?awinmid=26429&#038;awinaffid=2675822&#038;ued=https%3A%2F%2Flink.springer.com%2Fbook%2F10.1007%2F978-3-032-08199-5" rel="nofollow" target="_blank"><img src="https://i0.wp.com/www.statforbiology.com/Figures/Email_Signature_978-3-032-08199-5.png?w=578&#038;ssl=1" alt="Book cover" class="cover" align="center" data-recalc-dims="1"></a></p>
<hr>
</section>
<section id="further-readings" class="level1">
<h1>Further readings</h1>
<ol type="1">
<li>Miguez, F., Archontoulis, S., Dokoohaki, H., Glaz, B., Yeater, K.M., 2018. Chapter 15: Nonlinear Regression Models and Applications, in: ACSESS Publications. American Society of Agronomy, Crop Science Society of America, and Soil Science Society of America, Inc.</li>
<li>Ratkowsky, D.A., 1990. Handbook of nonlinear regression models. Marcel Dekker Inc., New York, USA.</li>
<li>Ritz, C., Jensen, S. M., Gerhard, D., Streibig, J. C., 2019. Dose-Response Analysis Using R. CRC Press</li>
<li>Schabenberger, O., Pierce, F.J., 2002. Contemporary statistical models for the plant and soil sciences. Taylor &#038; Francis, CRC Press, Books.</li>
</ol>
<p>This post was originally published in this blog on 2019-01-08</p>


</section>

 
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://www.statforbiology.com/posts/nls_usefulEquations.html"> Statforbiology</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/some-useful-equations-for-biological-processes/">Some useful equations for biological processes</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402841</post-id>	</item>
		<item>
		<title>Babe Ruth:  How good was he?  Mantle versus Ruth</title>
		<link>https://www.r-bloggers.com/2026/07/babe-ruth-how-good-was-he-mantle-versus-ruth/</link>
		
		<dc:creator><![CDATA[Jerry Tuttle]]></dc:creator>
		<pubDate>Thu, 23 Jul 2026 13:40:56 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">http://www.r-bloggers.com/?guid=5d604b1e3883f211bead13b9aee0a3ea</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>     <br />
  As a kid, my baseball hero was Mickey Mantle.  In his 18-year Major League career, he amassed tremendous statistics, and surely he was one of the game's all-time greats. When Mantle retired, he was third on...</p></div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/babe-ruth-how-good-was-he-mantle-versus-ruth/">Babe Ruth:  How good was he?  Mantle versus Ruth</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://onlinecollegemathteacher.blogspot.com/2026/07/babe-ruth-how-good-was-he-mantle-versus.html"> Online College Math Teacher</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<font size = 3>
  
  
  <div class="separator" style="clear: both;"><a href="https://i0.wp.com/blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCCmsSfa9WIoWzQAP-ZBXO_SBQqll6JMXhJEjdON2COM4C6AQtwUyfrYrFogPc3rEtkSvs6327YWzDdT_Rt3XPEuupvMvxC8ygDnD_lw8OCX8WHzFLF9oxJf9hW1wwNb9iYogPAqUEgH-ATGrYGyhvJ8lPS5DuZkk5Z2p4VPpuxETa_cTHCCUZogT8QDo/s697/mick_babe.jpg?ssl=1" style="display: block; padding: 1em 0; text-align: center; " rel="nofollow" target="_blank"><img alt="" border="0" width="400" data-original-height="400" data-original-width="450" src="https://i0.wp.com/blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCCmsSfa9WIoWzQAP-ZBXO_SBQqll6JMXhJEjdON2COM4C6AQtwUyfrYrFogPc3rEtkSvs6327YWzDdT_Rt3XPEuupvMvxC8ygDnD_lw8OCX8WHzFLF9oxJf9hW1wwNb9iYogPAqUEgH-ATGrYGyhvJ8lPS5DuZkk5Z2p4VPpuxETa_cTHCCUZogT8QDo/s400/mick_babe.jpg?resize=400%2C400&#038;ssl=1" data-recalc-dims="1"/></a></div>
  
     
  As a kid, my baseball hero was Mickey Mantle.  In his 18-year Major League career, he amassed tremendous statistics, and surely he was one of the game&#8217;s all-time greats. When Mantle retired, he was third on the all-time career home run list with 536 home runs, trailing only Babe Ruth (714) and Willie Mays (587). Unfortunately, he suffered numerous injuries, leaving fans to wonder what his numbers would look like if he had enjoyed a healthier career. <p>
  
     
  For decades many people considered (and still consider) Babe Ruth to be the greatest all-around baseball player, because he was a star pitcher and a star hitter.  The counter-argument to the Mantle &#8220;what-if&#8221; is:  what if Ruth had not spent his first six years as a pitcher and instead had been a full-time hitter? (Similarly, what if Ted Williams had not spent some of his prime years in the military.) <p>
  
     
  Nowadays Shohei Ohtani is certainly a once-in-a-generation two-way star.  However, he spent his early prime years in Japan&#8217;s professional baseball, and he may not have enough time left in US baseball to amass these historic lifetime stats.  Aaron Judge is another exceptional modern hitter; hopefully, he stays healthy so we can watch his career numbers climb.  <p>
  
     
  To compare Mantle and Ruth’s lifetime stats objectively, I turned to data. The Sean Lahman baseball dataset contains Major League player stats back to 1871, and is available in the R library <i>lahman</i>.  This was a good opportunity to practice data manipulation using <i>dplyr</i>. <p>
  
     
  
  Ruth played 102 more games than Mantle over a 22-year career (2,503 versus 2,401). His lifetime statistics eclipse Mantle&#8217;s in every offensive category except stolen bases — though Ruth did steal home 10 times and hit nearly twice as many triples, suggesting he was faster than most realize. His lifetime batting average was an impressive .342, sitting just behind Tris Speaker and Ted Williams. <p>
  
     
  
  Lineup protection played a massive role for both men. Ruth generally batted directly before Lou Gehrig, and Mantle batted directly before Yogi Berra. While both Ruth and Mantle drew plenty of walks, presumably pitchers rarely chose to walk them intentionally just to face Gehrig or Berra. <p>
  
     
  
  I was also curious about their defensive metrics. For a fair comparison, I filtered the data to isolate only their outfield appearances. There is no value in comparing an outfield throw to an assist Ruth made on a comeback grounder while pitching. Similarly, I excluded Mantle&#8217;s infield appearances; he primarily played first base in his final two seasons and filled in briefly at other infield spots early in his career. <p>
  
     
  
  Ruth played 222 more outfield games than Mantle (2,241 versus 2,019). Their total outfield putouts were nearly identical, likely because Mantle played centerfield and covered more ground. However, Ruth recorded nearly twice as many outfield assists (204 versus 117), which aligns with the arm strength expected of a former pitcher. While Ruth&#8217;s 204 assists don&#8217;t match stars such as Roberto Clemente&#8217;s 266, it remains a highly respectable number. <p>
  
     
  Ultimately, the data shows that even if you completely ignore his pitching career, Babe Ruth built an outstanding, standalone career as both a hitter and a fielder. <p>
  
<pre>
              
          MANTLE  RUTH
games       2401  2503
at_bats     8102  8398
runs        1677  2174
hits        2415  2873
doubles      344   506
triples       72   136
home_runs    536   714
BA         0.298 0.342
rbi         1509  2217
sb           153   123
bb          1733  2062
so          1710  1330
games_of    2019  2241
putouts     4438  4444
assists      117   204

</pre><p>  
  
      
  Here is my R code:<p>
  
<pre>
library(Lahman)
library(tidyverse)

data(People)
which(People$nameLast == &quot;Mantle&quot;)   # 11773,  playerID = mantlmi01
which(People$nameLast == &quot;Ruth&quot;)   # 16674 , playerID = ruthba01 
data(Batting)    
data(Fielding)   # for fielding, want games in outfield POS == 'OF'

df_fielding &lt;- Fielding %&gt;% 
  filter(playerID %in% c('mantlmi01', 'ruthba01'), POS == 'OF') %&gt;% 
  group_by(playerID) %&gt;% 
  summarize(games_of = sum(G, na.rm = TRUE), putouts = sum(PO, na.rm = TRUE),
    assists = sum(A, na.rm = TRUE)
  )

df &lt;- Batting %&gt;% 
  filter(playerID %in% c('mantlmi01', 'ruthba01')) %&gt;% 
   group_by(playerID) %&gt;% 
   summarize(games = sum(G, na.rm = TRUE), at_bats = sum(AB, na.rm = TRUE),
                runs = sum(R, na.rm = TRUE), hits = sum(H, na.rm = TRUE),
                doubles = sum(X2B, na.rm = TRUE), 
                triples = sum(X3B, na.rm = TRUE), home_runs = sum(HR, na.rm = TRUE),
                BA = round(hits / at_bats,3), 
                rbi = sum(RBI, na.rm = TRUE),  sb = sum(SB, na.rm = TRUE),
                bb = sum(BB, na.rm = TRUE),  so = sum(SO, na.rm = TRUE),
                )  %&gt;%
  merge(df_fielding, by = &quot;playerID&quot;, all.x = TRUE) 

df_transposed &lt;- as.data.frame(t(df))
colnames(df_transposed) &lt;- c(&quot;MANTLE&quot;, &quot;RUTH&quot;)
df_transposed &lt;- df_transposed[-1, ]
df_transposed

</pre><p>
  
End
</font>
                 
                 
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://onlinecollegemathteacher.blogspot.com/2026/07/babe-ruth-how-good-was-he-mantle-versus.html"> Online College Math Teacher</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/babe-ruth-how-good-was-he-mantle-versus-ruth/">Babe Ruth:  How good was he?  Mantle versus Ruth</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402791</post-id>	</item>
		<item>
		<title>New Frontier</title>
		<link>https://www.r-bloggers.com/2026/07/new-frontier/</link>
		
		<dc:creator><![CDATA[Stephen Royle]]></dc:creator>
		<pubDate>Thu, 23 Jul 2026 10:45:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://quantixed.org/?p=3820</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> Remember the “AI rat penis” incident at Frontiers in Cell &#038; Developmental Biology? Well, that was two and a half years ago. That’s enough water under the bridge to now check in and see how this incident affected the journal. If we look at how many papers published, we should ...</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/new-frontier/">New Frontier</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://quantixed.org/2026/07/23/new-frontier/"> Rstats – quantixed</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>

<p class="wp-block-paragraph">Remember the “AI rat penis” incident at Frontiers in Cell &#038; Developmental Biology?</p>



<div data-wp-context="{ "autoclose": false, "accordionItems": [] }" data-wp-interactive="core/accordion" role="group" class="wp-block-accordion is-layout-flow wp-block-accordion-is-layout-flow">
<div data-wp-class--is-open="state.isOpen" data-wp-context="{ "id": "accordion-item-1", "openByDefault": false }" data-wp-init="callbacks.initAccordionItems" data-wp-on-window--hashchange="callbacks.hashChange" class="wp-block-accordion-item is-layout-flow wp-block-accordion-item-is-layout-flow">
<h3 class="wp-block-accordion-heading"><button aria-expanded="false" aria-controls="accordion-item-1-panel" data-wp-bind--aria-expanded="state.isOpen" data-wp-on--click="actions.toggle" data-wp-on--keydown="actions.handleKeyDown" id="accordion-item-1" type="button" class="wp-block-accordion-heading__toggle"><span class="wp-block-accordion-heading__toggle-title">What “AI rat penis” incident? (click here if you don’t remember)</span><span class="wp-block-accordion-heading__toggle-icon" aria-hidden="true">+</span></button></h3>



<div inert aria-labelledby="accordion-item-1" data-wp-bind--inert="!state.isOpen" id="accordion-item-1-panel" role="region" class="wp-block-accordion-panel is-layout-flow wp-block-accordion-panel-is-layout-flow">
<p class="wp-block-paragraph">In Feb 2024, Frontiers in Cell &#038; Developmental Biology published a review paper with two comically bad AI-generated figures. In the first, a rat had a rather large organ. In the second, there was a nonsensical signalling pathway. Both figures had garbled labels. I won’t reproduce them here, but the paper (since retracted) is <a href="https://doi.org/10.3389/fcell.2023.1339390" rel="nofollow" target="_blank">here</a>. An example news piece covering the furore at The Vice is <a href="https://www.vice.com/en/article/scientific-journal-frontiers-publishes-ai-generated-rat-with-gigantic-penis-in-worrying-incident/" rel="nofollow" target="_blank">here</a>.</p>
</div>
</div>
</div>



<p class="wp-block-paragraph">Well, that was two and a half years ago. That’s enough water under the bridge to now check in and see how this incident affected the journal. If we look at how many papers published, we should be able to see whether the incident affected submissions.</p>



<p class="wp-block-paragraph">I will say upfront that <strong>this analysis did not reveal what I thought it would</strong>. It’s well known that Frontiers journals had huge growth some years ago and I also knew that submissions had decreased in the last few years. So, I expected that this drop off was due to authors not wanting to publish in the journal after the AI figure debacle or perhaps a combination of that and the <a href="https://doi.org/10.1162/qss_a_00327" rel="nofollow" target="_blank">study</a> by Mark Hanson and colleagues showing suspiciously fast turnaround times at journals, including titles from this publisher.</p>



<p class="wp-block-paragraph">The plots can be quickly generated using <code>{PubMedLagR}</code> which is available <a href="https://github.com/quantixed/PubMedLagR" rel="nofollow" target="_blank">here</a>.</p>



<p class="wp-block-paragraph">Jump to the <a href="https://quantixed.org/2026/07/23/new-frontier/#code" data-type="internal" data-id="#code" rel="nofollow" target="_blank">code</a>, or just look at the plots.</p>



<p class="wp-block-paragraph">If we pull all the articles in PubMed for this journal and see how many were published per month, we get a plot like this. The dotted line shows the date of the rat penis incident.</p>



<figure data-wp-context="{"imageId":"6a61ff7ec2578"}" data-wp-interactive="core/image" data-wp-key="6a61ff7ec2578" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" fetchpriority="high" decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://i2.wp.com/quantixed.org/wp-content/uploads/2026/07/frontiers-1024x768.png?w=450&#038;ssl=1" alt="" class="wp-image-3821" srcset_temp="https://i2.wp.com/quantixed.org/wp-content/uploads/2026/07/frontiers-1024x768.png?w=450&#038;ssl=1 1024w, https://quantixed.org/wp-content/uploads/2026/07/frontiers-300x225.png 300w, https://quantixed.org/wp-content/uploads/2026/07/frontiers-768x576.png 768w, https://quantixed.org/wp-content/uploads/2026/07/frontiers-1536x1152.png 1536w, https://quantixed.org/wp-content/uploads/2026/07/frontiers-2048x1536.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" data-recalc-dims="1" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">So there was a huge boom in publications in the COVID-19 pandemic era and then a decrease. This decrease predates the rat penis incident. If anything, the number of papers published began to stabilise and perhaps even recover following the incident!</p>



<p class="wp-block-paragraph">It’s a bit hard to see if the composition of articles has changed over time from the plot above. So let’s replot these data and look at the fraction of all articles that are papers versus other types. I did some spot-checking and there were several papers that are clearly Commentary, Editorial and Review types that are not properly tagged on PubMed. So take this with a pinch of salt. The articles are split 50:50 between papers and other types and this has not really changed. It could be argued that commissioned content might be unaffected whereas as directly submitted papers might drop off if authors were concerned about a journal. But there’s no evidence of that here.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" src="https://i2.wp.com/quantixed.org/wp-content/uploads/2026/07/frontiers_scaled-1024x768.png?w=450&#038;ssl=1" alt="" class="wp-image-3822" srcset_temp="https://i2.wp.com/quantixed.org/wp-content/uploads/2026/07/frontiers_scaled-1024x768.png?w=450&#038;ssl=1 1024w, https://quantixed.org/wp-content/uploads/2026/07/frontiers_scaled-300x225.png 300w, https://quantixed.org/wp-content/uploads/2026/07/frontiers_scaled-768x576.png 768w, https://quantixed.org/wp-content/uploads/2026/07/frontiers_scaled-1536x1152.png 1536w, https://quantixed.org/wp-content/uploads/2026/07/frontiers_scaled-2048x1536.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" data-recalc-dims="1" /></figure>



<p class="wp-block-paragraph">This is looking at published papers. Obviously this metric lags behind the author behaviour we’re interested in. Did the rat penis incident affect <em>submissions</em> to the journal? We can look at the received dates of published papers:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" src="https://i1.wp.com/quantixed.org/wp-content/uploads/2026/07/frontiers_subs-1024x768.png?w=450&#038;ssl=1" alt="" class="wp-image-3823" srcset_temp="https://i1.wp.com/quantixed.org/wp-content/uploads/2026/07/frontiers_subs-1024x768.png?w=450&#038;ssl=1 1024w, https://quantixed.org/wp-content/uploads/2026/07/frontiers_subs-300x225.png 300w, https://quantixed.org/wp-content/uploads/2026/07/frontiers_subs-768x576.png 768w, https://quantixed.org/wp-content/uploads/2026/07/frontiers_subs-1536x1152.png 1536w, https://quantixed.org/wp-content/uploads/2026/07/frontiers_subs-2048x1536.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" data-recalc-dims="1" /></figure>



<p class="wp-block-paragraph">Pretty much the same story: month-on-moth submission are steadily rising after the incident.</p>



<p class="wp-block-paragraph">Obviously we only have submission data for papers that were eventually published in the journal. We don’t know what the rejection rate was over this period. It would be possible for a beleaguered journal to reduce the rejection rate to stabilise the numbers of papers it publishes. But if we assume the rejection rate is constant, then submissions follow similar dynamics.</p>



<p class="wp-block-paragraph"><strong>Conclusion: the AI debacle didn’t negatively affect submissions at this journal.</strong></p>



<p class="wp-block-paragraph">Maybe potential authors were unaware of this issue (although there was plenty of publicity), or maybe they view the incident as a one-off, or perhaps they’re not concerned about science integrity issues.</p>



<p class="wp-block-paragraph">It’s no secret that the biggest drivers of journal choice for authors are 1) the journal impact factor and 2) the turnaround time/hassle to publish the work. The journals with the highest impact factor and the fastest turnaround win big. A scandal like this doesn’t seem to have affected journal choice. Of course, this is just a simple analysis and there are many factors at play here.</p>



<p class="wp-block-paragraph">Isn’t it ironic though that authors want to publish in a journals with high impact factors? They want their paper to be viewed as potentially highly citable because of where it is published; but if that means that their paper appeared in a journal that has a scientific integrity issue, the cry is “judge the paper on its own merits, not where it’s published”…</p>



<h2 id="code" class="wp-block-heading">The code</h2>


<pre>
library(PubMedLagR)
library(ggplot2)

retrieve_journal_year_records(&quot;Front Cell Dev Biol&quot;, 2015:2026, batch_size = 200, papers_only = FALSE)
all &lt;- pubmed_xmls_to_df(clean = FALSE)
# remove duplicate rows
all &lt;- all[!duplicated(all),]
# clear Data/ and then
retrieve_journal_year_records(&quot;Front Cell Dev Biol&quot;, 2015:2026, batch_size = 200)
pprs &lt;- pubmed_xmls_to_df()
# classify the papers in all
all$paper &lt;- ifelse(all$pmid %in% unique(pprs$pmid),&quot;paper&quot;, &quot;other&quot;)
# convert publication date to the first of the month
all$year_month &lt;- as.Date(paste0(substr(all$pubdate,1,7),&quot;-01&quot;))

# frontiers colours for fun
x &lt;- c(&quot;242 130 91&quot;, &quot;24 157 196&quot;)
fcolours &lt;- sapply(strsplit(x, &quot; &quot;), function(x)
  rgb(x[1], x[2], x[3], maxColorValue=255))

# ggplot of number of papers per month-year
p1 &lt;- ggplot(all, aes(x = year_month, fill = paper)) +
  geom_bar() +
  scale_fill_manual(values = fcolours) +
  geom_vline(xintercept = as.POSIXct(as.Date(&quot;2024-02-14&quot;)), linetype=2) +
  labs(x = &quot;&quot;, y = &quot;Papers per month&quot;) +
  theme_classic()
p1

# stacked plot version
p2 &lt;- ggplot(all, aes(x = year_month, fill = paper)) +
  geom_bar(position = &quot;fill&quot;) +
  scale_fill_manual(values = fcolours) +
  geom_vline(xintercept = as.POSIXct(as.Date(&quot;2024-02-14&quot;)), linetype=2) +
  labs(x = &quot;&quot;, y = &quot;Composition&quot;) +
  theme_classic()
p2

# what about submissions?
all$sub_year_month &lt;- as.Date(paste0(substr(all$recdate,1,7),&quot;-01&quot;))
p3 &lt;- ggplot(all, aes(x = sub_year_month, fill = paper)) +
  geom_bar() +
  scale_fill_manual(values = fcolours) +
  geom_vline(xintercept = as.POSIXct(as.Date(&quot;2024-02-14&quot;)), linetype=2) +
  labs(x = &quot;&quot;, y = &quot;Papers per month&quot;) +
  theme_classic()
p3
</pre>


<p class="wp-block-paragraph">I added some styling to the plots to post them here, but the code will give the same three plots as in the post.</p>



<p class="wp-block-paragraph">—</p>



<p class="wp-block-paragraph">The post title comes from “New Frontier” by Donald Fagen from his 1982 “The Nightfly” LP.</p>

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://quantixed.org/2026/07/23/new-frontier/"> Rstats – quantixed</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/new-frontier/">New Frontier</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402786</post-id>	</item>
		<item>
		<title>controller: tidy messy terminology in R with controlled vocabularies</title>
		<link>https://www.r-bloggers.com/2026/07/controller-tidy-messy-terminology-in-r-with-controlled-vocabularies/</link>
		
		<dc:creator><![CDATA[Joe Roe]]></dc:creator>
		<pubDate>Thu, 23 Jul 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://joeroe.io/2026/07/23/controller-0.1.0</guid>

					<description><![CDATA[<p>controller is an R package for working with controlled vocabularies.<br />
It’s first release (v0.1.0) is now available now on CRAN.</p>
<p>The package addresses something I find myself doing very often in analysis code: tidying messy and inconsistent terminologi...</p>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/controller-tidy-messy-terminology-in-r-with-controlled-vocabularies/">controller: tidy messy terminology in R with controlled vocabularies</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://joeroe.io/2026/07/23/controller-0.1.0.html"> Joe Roe</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<p><a href="https://controller.joeroe.io/" rel="nofollow" target="_blank">controller</a> is an R package for working with controlled vocabularies. 
It’s first release (v0.1.0) is now available now <a href="https://cran.r-project.org/package=controller" rel="nofollow" target="_blank">on CRAN</a>.</p>

<p>The package addresses something I find myself doing very often in analysis code: tidying messy and inconsistent terminologies.
For smaller datasets, <code>dplyr::recode()</code> is okay for this, but writing the mapping out as an R function call gets tedious fast when dealing with a long list of terms.
It becomes <em>very</em> tedious when you have variants distinguished only by things like capitalisation (<code>OxA-</code> vs. <code>oxa-</code>), word boundaries (<code>Çatalhöyük</code> vs. <code>Çatal Höyük</code>) or character encoding (<code>ʿAin Ghazal</code> vs. <code>ʽAyn Ghazal</code>).</p>

<p>controller instead defines preferred terms and their variants in a data frame.
Its <code>control()</code> verb is the equivalent of <code>dplyr::recode()</code> but using this thesaurus and with a few extra bells and whistles for fuzzy matching and reporting what was (and wasn’t) changed:</p>

<pre>library(controller)
data(&quot;colour_thesaurus&quot;)

shades &lt;- c(&quot;daffodil&quot;, &quot;purple&quot;, &quot;magenta&quot;, &quot;azure&quot;, &quot;navy&quot;, &quot;violet&quot;)
control(shades, colour_thesaurus)
#&gt; Replaced values:
#&gt; &#x2139; daffodil → yellow
#&gt; &#x2139; azure → blue
#&gt; &#x2139; navy → blue
#&gt; &#x2139; violet → purple
#&gt; Warning: Some values of `x` were not matched in `thesaurus`:
#&gt; &#x2716; magenta
</pre>

<p>Fuzzy matching means we don’t need to exhaustively list those variants from things like differences in case, word boundaries, or character encoding:</p>

<pre>control_ci(toupper(shades), colour_thesaurus)
#&gt; Replaced values:
#&gt; &#x2139; DAFFODIL → yellow
#&gt; &#x2139; PURPLE → purple
#&gt; &#x2139; AZURE → blue
#&gt; &#x2139; NAVY → blue
#&gt; &#x2139; VIOLET → purple
#&gt; [1] &quot;yellow&quot;  &quot;purple&quot;  &quot;MAGENTA&quot; &quot;blue&quot;    &quot;blue&quot;    &quot;purple&quot;
#&gt; Warning message:
#&gt; Some values of `x` were not matched in `thesaurus`:
#&gt; &#x2716; MAGENTA
</pre>

<hr />

<p>This package has been hanging around for a while!
It started off as a helper function I used for cleaning up site names from prehistoric sites in Southwest Asia.
The basic idea was inspired by similar functions that used to exist in <a href="https://github.com/ISAAKiel/c14bazAAR" rel="nofollow" target="_blank">c14bazAAR</a> for cleaning sample metadata for radiocarbon date, that I thought were quite neat.
So when the maintainers of that package decided to deprecate those, I took over the thesauri as part of <a href="https://c14.joeroe.io/" rel="nofollow" target="_blank">c14</a> and spun the supporting functions off into controller as a standalone package.
Then over the years it acquired some more functionality for working with controlled vocabularies (a surprising gap in the R ecosystem), like reading heritage vocabularies in <a href="https://heritage-standards.org.uk/fish-vocabularies/" rel="nofollow" target="_blank">Historic England’s FISH format</a>.
Five years later, I am finally getting around to releasing it on CRAN because I need to release c14 on CRAN, because <em>that’s</em> used in analyses I’m now publishing.
It’s the research software engineering of <a href="https://www.youtube.com/watch?v=5W4NFcamRhM" rel="nofollow" target="_blank">changing a lightbulb</a>, basically.</p>

<hr />

<p>The first release of controller includes:</p>

<ul>
  <li><code>control()</code>, <code>control_ci()</code>, and <code>control_fuzzy()</code> for recoding values</li>
  <li><code>control_names()</code>, <code>control_names_ci()</code>, and <code>control_names_fuzzy()</code> for recoding names</li>
  <li><code>control_matches()</code> for inspecting how matches were made</li>
  <li><code>read_fish()</code> for reading vocabularies in <a href="https://heritage-standards.org.uk/fish-vocabularies/" rel="nofollow" target="_blank">Historic England’s FISH format</a></li>
  <li><code>colour_thesaurus</code>, an example dataset</li>
</ul>

<p>You can install it from CRAN:</p>

<pre>install.packages(&quot;controller&quot;)
</pre>

<p>Or the development version from GitHub:</p>

<pre>remotes::install_github(&quot;joeroe/controller&quot;)
</pre>

<p>You can find the full documentation at <a href="https://controller.joeroe.io/" rel="nofollow" target="_blank">https://controller.joeroe.io</a>.</p>
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://joeroe.io/2026/07/23/controller-0.1.0.html"> Joe Roe</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/controller-tidy-messy-terminology-in-r-with-controlled-vocabularies/">controller: tidy messy terminology in R with controlled vocabularies</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402802</post-id>	</item>
		<item>
		<title>muttest 0.3.0: Turn surviving mutants into a to-do list</title>
		<link>https://www.r-bloggers.com/2026/07/muttest-0-3-0-turn-surviving-mutants-into-a-to-do-list/</link>
		
		<dc:creator><![CDATA[Jakub Sobolewski]]></dc:creator>
		<pubDate>Wed, 22 Jul 2026 22:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://jakubsobolewski.com/blog/muttest-0_3_0</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> HTML and JSON reporting, and smarter scoring for mutation testing in R.</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/muttest-0-3-0-turn-surviving-mutants-into-a-to-do-list/">muttest 0.3.0: Turn surviving mutants into a to-do list</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://jakubsobolewski.com/blog/muttest-0_3_0"> Jakub Sobolewski</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<p><img src="https://i1.wp.com/jakubsobolewski.com/blog/muttest-0_3_0/og-image.png?w=578&#038;ssl=1" alt="muttest 0.3.0: Turn surviving mutants into a to-do list" data-recalc-dims="1" /></p><p><a href="https://github.com/jakubsob/muttest" rel="nofollow" target="_blank"><code>muttest</code></a> so far only printed to the console which mutants were killed and which survived.</p>
<p>That’s the minimal setup you need to act on mutation testing findings, but it’s far from optimal. Clear the terminal, close the IDE, and the results are gone unless you saved the output.</p>
<p><code>muttest@0.3.0</code> fixes that with an HTML report.</p>
<ol>
<li>Run your tests with new JSON reporter.</li>
<li>Render the report.</li>
<li>Open it in your browser, and every mutant is laid over your source code.</li>
</ol>
<p>Click the ones that survived and see exactly what slipped past your suite. That list of survivors is your to-do list: every one is a candidate test. You decide which are worth writing and which are just noise.</p>
<blockquote>
<p><img src="https://s.w.org/images/core/emoji/13.0.0/72x72/1f4dd.png" alt="📝" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Read the full changelog <a href="https://github.com/jakubsob/muttest/blob/main/NEWS.md" rel="nofollow" target="_blank">here</a>.</p>
</blockquote>
<h2 id="new-to-mutation-testing">New to mutation testing?</h2>
<p>Coverage tells you which lines ran. It says nothing about whether your tests would notice if those lines were wrong. You can delete every assertion in your suite, run <code>covr</code>, and still see 100%.</p>
<p>Mutation testing asks the harder question: <em>if this code were subtly broken, would a test fail?</em> It makes small changes to your source (<code>&gt;</code> becomes <code>&gt;=</code>, <code>TRUE</code> becomes <code>FALSE</code>) and reruns your tests against each version. Each changed version is a <strong>mutant</strong>. If a test fails, the mutant is <strong>killed</strong>. If every test still passes, the mutant <strong>survived</strong>, and you’ve found a gap.</p>
<p>A surviving mutant isn’t a bug to fix. It’s a missing test that could hide an expensive bug later.</p>
<p>If you want to dive deeper, the <a href="https://jakubsobolewski.com/blog/muttest-0_2_0" rel="nofollow" target="_blank">0.2.0 post</a> walks through it with an example.</p>
<h2 id="the-report">The report</h2>
<p>Run your mutation tests with <code>JSONMutationReporter</code>, call <code>report()</code>, and you get a self-contained HTML file.</p>
<p><img alt="HTML report" loading="lazy" decoding="async" fetchpriority="auto" width="450" src="https://jakubsobolewski.com/_astro/1.BnUOu2qB_Z2dRrSv.webp" ></p>
<p><img alt="HTML report" loading="lazy" decoding="async" fetchpriority="auto" width="450" src="https://jakubsobolewski.com/_astro/2.MUnYt7vW_Z1vdtA.webp" ></p>
<p>See the full example report <a href="https://jakubsob.github.io/muttest/report/muttest.html" rel="nofollow" target="_blank">here</a>.</p>
<p>Here’s what the report does that the console can’t do:</p>
<ul>
<li><strong>Your source code annotated with mutants.</strong> Every file is shown with its actual code, and each mutated line is marked inline. You read the survivor in context instead of reconstructing where a given line was.</li>
<li><strong>Per-file scores.</strong> The overall number is a starting point, not a diagnosis. The report breaks the score down by file, so you can see your parser sitting at 95% while the validation module is at 40%. That tells you which file to open first.</li>
<li><strong>Per-line mutant diffs.</strong> Click a mutant and see exactly what changed: the original line, the mutated line, and whether your tests killed it. When something survived, the diff tells you what kind of a potential bug slipped through.</li>
<li><strong>Filter by status.</strong> The report opens focused on survivors, since the killed mutants already did their job. You can bring the others back when you want the full picture, but the default is the view you actually came for.</li>
<li><strong>Keyboard navigation.</strong> Step through mutants without scrolling through the whole file.</li>
</ul>
<p>That’s the workflow – filter to survivors, walk the list top to bottom, and each one is a decision: write the test, or call it noise and move on.</p>
<p>A checklist you can work through.</p>
<h2 id="json-output">JSON output</h2>
<p>The new <code>JSONMutationReporter</code> writes results to a file that conforms to the <a href="https://github.com/stryker-mutator/mutation-testing-elements/blob/master/packages/report-schema/src/mutation-testing-report-schema.json" rel="nofollow" target="_blank">mutation-testing-elements</a> schema. That schema isn’t something I invented. It’s the format shared by StrykerJS, Stryker.NET, Stryker for Scala, and others. If other teams in your organization already use Stryker and its reporting tools, you can plug <code>muttest</code> results straight into the same dashboards.</p>
<pre>library(muttest)

plan &lt;- muttest_plan(
  source_files = &quot;R/shipping.R&quot;,
  mutators = comparison_operators()
)

muttest(plan, reporter = JSONMutationReporter$new())

report()</pre>
<p><code>JSONMutationReporter</code> writes to <code>muttest.json</code> by default, and <code>report()</code> reads that same file and writes <code>muttest.html</code> next to it, so with the defaults there’s nothing to wire up.</p>
<p>If you don’t like the built-in report, the JSON file is there to build your own. I plan to keep this schema stable so don’t worry about your report breaking with every next release.</p>
<h2 id="watch-it-run-save-it-for-later">Watch it run, save it for later</h2>
<p>You usually want both: a live progress table while the run happens, and a saved file to open afterward. Before, you picked one reporter and got one behavior.</p>
<p><code>MultiReporter</code> runs several reporters at once. Feed it a <code>ProgressMutationReporter</code> and a <code>JSONMutationReporter</code> together. The console fills up as mutants are tested, and the JSON file is waiting when it’s done.</p>
<pre>muttest(
  plan,
  reporter = MultiReporter$new(
    ProgressMutationReporter$new(),
    JSONMutationReporter$new()
  )
)</pre>
<p>It’s exactly the same idea as <code>testthat</code>’s <a href="https://testthat.r-lib.org/reference/MultiReporter.html" rel="nofollow" target="_blank"><code>MultiReporter</code></a>.</p>
<h2 id="scoring-changes-worth-knowing-about">Scoring changes worth knowing about</h2>
<p>Two changes in this release will move your score:</p>
<ul>
<li><strong>Errored mutants now count as killed.</strong> Some mutations don’t just fail an expectation; they make the code throw before a test can even assert anything. A mutation that produces an error is still a mutation your suite detected, so 0.3.0 scores it as killed. This matches PIT, Stryker, and mutmut. Previously <code>muttest</code> counted these as survived, which was too harsh: the test <em>did</em> catch the change, it just caught it by blowing up.</li>
<li><strong>Uncovered code gets its own category.</strong> Under <code>FileTestStrategy</code>, a mutant in a source file with no matching test file used to look identical to a mutant your tests ran and missed. Those are different problems. A survived mutant means your tests are weak; an uncovered mutant means there are no tests at all. 0.3.0 reports uncovered mutants as a separate <code>no coverage</code> category and leaves them out of the score, so untested code stops masquerading as escaped mutants and dragging your number down for the wrong reason.</li>
</ul>
<p>If your score shifts after upgrading, this is why. It’s more honest this way.</p>
<h2 id="tell-me-about-your-experience-of-using-muttest">Tell me about your experience of using <code>muttest</code></h2>
<p>I hope this release makes it easier to analyze results.</p>
<p><code>muttest</code> is still young and the interface may shift. If the report is missing something you’d want to see, if a mutation you care about has no way to be expressed, or if the new scoring surprises you in a way that feels wrong, open an issue on <a href="https://github.com/jakubsob/muttest/issues" rel="nofollow" target="_blank">GitHub</a>.</p>
<p>Feature requests are just as welcome as bug reports.</p>
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://jakubsobolewski.com/blog/muttest-0_3_0"> Jakub Sobolewski</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/muttest-0-3-0-turn-surviving-mutants-into-a-to-do-list/">muttest 0.3.0: Turn surviving mutants into a to-do list</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402804</post-id>	</item>
		<item>
		<title>Little useless-useful R functions – Jug solver with Bezout’s Identity</title>
		<link>https://www.r-bloggers.com/2026/07/little-useless-useful-r-functions-jug-solver-with-bezouts-identity/</link>
		
		<dc:creator><![CDATA[tomaztsql]]></dc:creator>
		<pubDate>Tue, 21 Jul 2026 19:15:27 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">http://tomaztsql.wordpress.com/?p=11182</guid>

					<description><![CDATA[<p>We all were presented with this problem – water jug problem, which – in the time of Football world cup 2026 – can be translated to any liquid. *hint hint* But the riddle is as logical as mathematical. With mathematics…Read more ›</p>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/little-useless-useful-r-functions-jug-solver-with-bezouts-identity/">Little useless-useful R functions – Jug solver with Bezout’s Identity</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://tomaztsql.wordpress.com/2026/07/21/little-useless-useful-r-functions-jug-solver-with-bezouts-identity/"> R – TomazTsql</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>

<p class="wp-block-paragraph">We all were presented with this problem – water jug problem, which – in the time of Football world cup 2026 – can be translated to any liquid. *hint hint*  But the riddle is as logical as mathematical. With mathematics finding the greatest common divisor. In general, it can be used with state search or Depth First Search (DFS). </p>



<p class="wp-block-paragraph">With DFS we can solve this with <a href="https://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity" rel="nofollow" target="_blank">Bezout’s identity;</a> which in general is a theorem which relates two arbitraty integers with their greatests common divisor; and used in algebraic language, finding common zeros of n-polznomials in n-indeterminates. So the common zeros equals the product of the degrees of the polynomials.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><a href="https://i0.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/07/water_jug_puzzle_solver-1.gif?ssl=1" rel="nofollow" target="_blank"><img loading="lazy" data-attachment-id="11189" data-permalink="https://tomaztsql.wordpress.com/2026/07/21/little-useless-useful-r-functions-jug-solver-with-bezouts-identity/water_jug_puzzle_solver-2/" data-orig-file="https://tomaztsql.wordpress.com/wp-content/uploads/2026/07/water_jug_puzzle_solver-1.gif" data-orig-size="480,320" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","alt":""}" data-image-title="Water_jug_puzzle_solver" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/07/water_jug_puzzle_solver-1.gif?w=450&#038;ssl=1" src="https://i0.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/07/water_jug_puzzle_solver-1.gif?w=450&#038;ssl=1" alt="" class="wp-image-11189" srcset_temp="https://tomaztsql.wordpress.com/wp-content/uploads/2026/07/water_jug_puzzle_solver-1.gif 480w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/07/water_jug_puzzle_solver-1.gif?w=150 150w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/07/water_jug_puzzle_solver-1.gif?w=300 300w" sizes="(max-width: 480px) 100vw, 480px" data-recalc-dims="1" /></a></figure>
</div>


<p class="wp-block-paragraph">And now that the imagine splitting the 16L <a href="https://www.thebeergiraffe.com/blog/what-is-a-beer-giraffe" rel="nofollow" target="_blank">beer Giraffe </a>in two 8L Giraffes but you are only using 11L and 7L empty giraffes <img src="https://i1.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png?w=578&#038;ssl=1" alt="&#x1f642;" class="wp-smiley" style="height: 1em; max-height: 1em;" data-recalc-dims="1" /> </p>



<p class="wp-block-paragraph">This is the proof that with beer, Algebra is more fun <img src="https://i1.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png?w=578&#038;ssl=1" alt="&#x1f642;" class="wp-smiley" style="height: 1em; max-height: 1em;" data-recalc-dims="1" /> And because it is fun, we can also find greated common divisors using Breadth-First Search (BFS). And here is the code:</p>



<pre>
solve_jugs &lt;- function(caps = c(16, 11, 7), start = c(16, 0, 0), goal = c(8, 8, 0)) {
  # BFS over all (a, b, c) states
  # Each state is a named integer vector of water = amount is each jug or ?????
  
  queue   &lt;- list(list(state = start, path = list(start)))
  visited &lt;- list()
  key     &lt;- function(s) paste(s, collapse = &quot;-&quot;)
  
  while (length(queue) &gt; 0) {
    node  &lt;- queue[[1]]
    queue &lt;- queue[-1]
    s     &lt;- node$state
    
    if (isTRUE(all(s == goal))) return(node$path)
    if (!is.null(visited[[key(s)]])) next
    visited[[key(s)]] &lt;- TRUE
    
    n &lt;- length(s)
    for (from in 1:n) {
      for (to in 1:n) {
        if (from == to || s[from] == 0 || s[to] == caps[to]) next
        
        pour    &lt;- min(s[from], caps[to] - s[to])
        new_s   &lt;- s
        new_s[from] &lt;- s[from] - pour
        new_s[to]   &lt;- s[to]   + pour
        
        if (is.null(visited[[key(new_s)]])) {
          queue &lt;- c(queue, list(list(
            state = new_s,
            path  = c(node$path, list(new_s))
          )))
        }
      }
    }
  }
  NULL  # no solution; add message or smht :)
}

solution &lt;- solve_jugs()

 
for (step in solution) {
  cat(sprintf(&quot;  %-4d  %-4d  %-4d\n&quot;, step[1], step[2], step[3]))
}
  </pre>



<p class="wp-block-paragraph">And the final solution will reveal the steps and actions:</p>



<pre>  16    0     0   
  5     11    0   
  5     4     7   
  12    4     0   
  12    0     4   
  1     11    4   
  1     8     7   
  8     8     0   
  </pre>



<p class="wp-block-paragraph">Similar steps are presented on the animation above.</p>



<p class="wp-block-paragraph">As always, the complete code is available on GitHub in  <a href="https://github.com/tomaztk/Useless_R_functions" rel="nofollow" target="_blank">Useless_R_function repository</a>. And code to the animation  is <a href="https://github.com/tomaztk/Useless_R_functions/blob/main/functions/WaterJugSolver_Animation.R" rel="nofollow" target="_blank">here</a> (same Github repository).</p>



<p class="wp-block-paragraph">Check the repository for future updates!</p>



<p class="wp-block-paragraph">Stay healthy, hydrated and happy R-coding!</p>



<p class="wp-block-paragraph"></p>

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://tomaztsql.wordpress.com/2026/07/21/little-useless-useful-r-functions-jug-solver-with-bezouts-identity/"> R – TomazTsql</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/little-useless-useful-r-functions-jug-solver-with-bezouts-identity/">Little useless-useful R functions – Jug solver with Bezout’s Identity</a>]]></content:encoded>
					
		
		<enclosure url="https://2.gravatar.com/avatar/84af3d4db7552aa6f0fc3db37b65871290b5174af7d5b84c3f185ca92ccfb237?s=96&#038;d=identicon&#038;r=G" length="0" type="" />
<enclosure url="https://tomaztsql.wordpress.com/wp-content/uploads/2026/07/water_jug_puzzle_solver-1.gif?w=480" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402745</post-id>	</item>
		<item>
		<title>A world still to be mapped: reflections on geocomputation in R: takeaways from the talk and workshop at UseR! 2026</title>
		<link>https://www.r-bloggers.com/2026/07/a-world-still-to-be-mapped-reflections-on-geocomputation-in-r-takeaways-from-the-talk-and-workshop-at-user-2026/</link>
		
		<dc:creator><![CDATA[Jakub Nowosad]]></dc:creator>
		<pubDate>Tue, 21 Jul 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://jakubnowosad.com/posts/2026-07-21-user/</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>At useR! 2026 in Warsaw, I contributed to a workshop on Geocomputation with R (July 6, 2026) and gave a keynote entitled A world still to be mapped: reflections on geocomputation in R (July 8, 2026). Both were opportunities to consider what the ...</p></div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/a-world-still-to-be-mapped-reflections-on-geocomputation-in-r-takeaways-from-the-talk-and-workshop-at-user-2026/">A world still to be mapped: reflections on geocomputation in R: takeaways from the talk and workshop at UseR! 2026</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://jakubnowosad.com/posts/2026-07-21-user/"> Thinking in spatial patterns</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
 





<p>At <a href="https://user2026.r-project.org/" rel="nofollow" target="_blank">useR! 2026</a> in Warsaw, I contributed to a workshop on <em>Geocomputation with R</em> (July 6, 2026) and gave a keynote entitled <em>A world still to be mapped: reflections on geocomputation in R</em> (July 8, 2026). Both were opportunities to consider what the R spatial ecosystem already makes possible, its strengths, limitations, and what remains to be done.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://jakubnowosad.com/user2026/" rel="nofollow" target="_blank"><img src="https://i1.wp.com/jakubnowosad.com/posts/2026-07-21-user/user2026-title-slide.png?w=578&#038;ssl=1" class="img-fluid figure-img" data-recalc-dims="1"></a></p>
<figcaption>Title slide of the talk</figcaption>
</figure>
</div>
<p><strong>Keynote slides:</strong> <a href="https://jakubnowosad.com/user2026/" class="uri" rel="nofollow" target="_blank">https://jakubnowosad.com/user2026/</a></p>
<p><strong>Workshop materials:</strong> <a href="https://github.com/geocompx/user26" class="uri" rel="nofollow" target="_blank">https://github.com/geocompx/user26</a></p>
<section id="workshop" class="level2">
<h2 class="anchored" data-anchor-id="workshop">Workshop</h2>
<p>The workshop, led by Jannes Muenchow and based on the second edition of <a href="https://r.geocompx.org/" rel="nofollow" target="_blank"><em>Geocomputation with R</em></a>, introduced some of the core building blocks of spatial work in R. It covered vector data with the <strong>sf</strong> package, raster data with the <strong>terra</strong> package, and spatial data visualization with the <strong>tmap</strong> package. I presented the visualization part, showing the main ingredients of the mapping workflow and demonstrating how maps can be used to explore geographic data and communicate analytical results.</p>
<p>These tools represent a mature and increasingly interoperable ecosystem. They make it possible to import, manipulate, analyze, and visualize geographic data while drawing on R’s wider capabilities for data processing and statistics. The workshop combined presentations, live coding, and exercises to provide a practical starting point for working with these tools. You can try the exercises yourself by following the instructions in <a href="https://github.com/geocompx/user26" rel="nofollow" target="_blank">the workshop materials</a>.</p>
</section>
<section id="talk" class="level2">
<h2 class="anchored" data-anchor-id="talk">Talk</h2>
<p>At UseR! 2026, <a href="https://jakubnowosad.com/user2026/" rel="nofollow" target="_blank">I spoke about geocomputation in R</a> through the lens of my work as a computational geographer. I started by showing that geography is not only about drawing maps or attaching coordinates to data. For me, it is a way of asking questions about what is happening, where it is happening, why it is happening there, and how those patterns change over time. To answer those questions, I use a combination of spatial data, statistical models, and visualization.</p>
<p>I also reflected on how far the R spatial ecosystem has come. Over the last few decades, R has grown into a strong environment for spatial analysis, with tools for vector and raster data, visualization, reproducibility, and integration with broader geospatial infrastructure. At the same time, some of the most important gaps are no longer just technical. We can keep building better packages, but that alone will not solve problems like weak validation practices or misleading maps – the challenge is not only to make better maps, but to make predictions and maps that we can trust. For these purposes, I discussed ideas such as prediction-domain adaptive evaluation in the context of spatial machine learning and the importance of proper color palettes and projection choices in the context of spatial visualization.</p>
<p>My conclusion was that the future of geocomputation in R depends as much on community as on code. The R spatial ecosystem is strong in scientific rigor, geospatial infrastructure, visualization, and reproducible workflows, but these strengths depend on an active community. Good spatial work still requires data, domain knowledge, careful evaluation, and honest communication. We should, therefore, continue building tools while also supporting people who maintain software, share examples and expertise, mentor others, and connect methods to real-world problems.</p>


</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre>@online{nowosad2026,
  author = {Nowosad, Jakub},
  title = {A World Still to Be Mapped: Reflections on Geocomputation in
    {R:} Takeaways from the Talk and Workshop at {UseR!} 2026},
  date = {2026-07-21},
  url = {https://jakubnowosad.com/posts/2026-07-21-user/},
  langid = {en}
}
</pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-nowosad2026" class="csl-entry quarto-appendix-citeas">
Nowosad, Jakub. 2026. <span>“A World Still to Be Mapped: Reflections on
Geocomputation in R: Takeaways from the Talk and Workshop at UseR!
2026.”</span> July 21. <a href="https://jakubnowosad.com/posts/2026-07-21-user/" rel="nofollow" target="_blank">https://jakubnowosad.com/posts/2026-07-21-user/</a>.
</div></div></section></div> 
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://jakubnowosad.com/posts/2026-07-21-user/"> Thinking in spatial patterns</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/a-world-still-to-be-mapped-reflections-on-geocomputation-in-r-takeaways-from-the-talk-and-workshop-at-user-2026/">A world still to be mapped: reflections on geocomputation in R: takeaways from the talk and workshop at UseR! 2026</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402715</post-id>	</item>
		<item>
		<title>Level With Me: Can the WGI Predict the WJP’s Rule of Law Scores?</title>
		<link>https://www.r-bloggers.com/2026/07/level-with-me-can-the-wgi-predict-the-wjps-rule-of-law-scores/</link>
		
		<dc:creator><![CDATA[Giles Dickenson-Jones]]></dc:creator>
		<pubDate>Mon, 20 Jul 2026 23:30:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://www.gilesd-j.com/?p=4254</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> TLDR: The first post established that the WGI and WJP rule of law measures agree on how they rank countries. […]<br />
The post Level With Me: Can the WGI Predict the WJP’s Rule of Law Scores? appeared first on Giles.</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/level-with-me-can-the-wgi-predict-the-wjps-rule-of-law-scores/">Level With Me: Can the WGI Predict the WJP’s Rule of Law Scores?</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://www.gilesd-j.com/2026/07/21/level-with-me-can-the-wgi-predict-the-wjps-rule-of-law-scores/"> Data Analytics and AI Archives - Giles</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>

<p class="wp-block-paragraph"><strong>TLDR:</strong> The first post established that the WGI and WJP rule of law measures agree on how they rank countries. This follow-up tests the stricter question of whether the WGI can predict the WJP’s <em>levels</em>, rather than just the relative ranking / relative position of countries. It can: forecasting errors appear to be minimal and don’t vary significantly over time.</p>



<p class="wp-block-paragraph"><em>This is second post in a series examining relationships between the rule of law and economic and social outcomes.</em></p>



<p class="wp-block-paragraph"><a href="https://www.gilesd-j.com/2026/07/07/close-enough-using-the-wgi-as-a-proxy-for-the-wjp-rule-of-law-index/https://www.gilesd-j.com/2026/07/07/close-enough-using-the-wgi-as-a-proxy-for-the-wjp-rule-of-law-index/" rel="nofollow" target="_blank">In the previous post in the series</a> I tested whether the World Governance Indicator’s (WGI) rule of law index (RoL) was a worthy substitute for the index produced by the World Justice Project when needing to take advantage of the WGI’s wider and longer coverage.</p>



<p class="wp-block-paragraph">When I asked Claude for feedback it rudely provided it, arguing that my analysis was fine for confirming <em>general agreement</em> as to how the two measures ranked countries, but additional analysis was needed to test whether the WGI could reliably be used to predict RoL levels.</p>



<p class="wp-block-paragraph">My first response was to tell Claude that <em>nobody </em>should be using composite indices in this way in the first place as it implied a level of precision they don’t have, but I decided it would be a useful addendum to the first post that I could post during my holiday in the Northern Territory.</p>



<h3 class="wp-block-heading">Project Setup and Data</h3>



<p class="wp-block-paragraph">Once again, data used in this post can be <a href="https://www.gilesd-j.com/2026/07/21/level-with-me-can-the-wgi-predict-the-wjps-rule-of-law-scores/gilesd-j.com/shared_resources/blogs/260310_RoL/wgidataset_with_sourcedata-2025.xlsx" rel="nofollow" target="_blank">downloaded here for the WGI</a> and <a href="https://www.gilesd-j.com/2026/07/21/level-with-me-can-the-wgi-predict-the-wjps-rule-of-law-scores/gilesd-j.com/shared_resources/blogs/260310_RoL/2025_wjp_rule_of_law_index_HISTORICAL_DATA_FILE.xlsx" rel="nofollow" target="_blank">here for the WJP’s RoL index</a>. These were current as of July 2025.</p>



<pre>#load the packages we'll probably need
library(tidyverse)
library(readxl)
library(janitor)
library(countrycode)

#import WGI data
dta_wgi_2025&lt;-read_excel(&quot;./Data/wgidataset_with_sourcedata-2025.xlsx&quot;,
                         sheet=&quot;rl&quot;) |&gt; 
  clean_names()

#import World Justice Project RoL data
dta_wjp_rol&lt;-read_excel('./Data/2025_wjp_rule_of_law_index_HISTORICAL_DATA_FILE.xlsx', sheet=&quot;Historical Data&quot;)|&gt; 
  clean_names()</pre>



<h3 class="wp-block-heading">Data Cleaning</h3>



<p class="wp-block-paragraph">Data cleaning is identical to the last post and revolves around making sure that countries names and regions are consistently applied across the two indices.</p>



<pre>#standardize column names
dta_wgi_2025&lt;-dta_wgi_2025 |&gt; 
  rename(country=economy_name,
         iso3c=economy_code,
         wgi_rol=governance_estimate_approx_2_5_to_2_5)

dta_wjp_rol&lt;-dta_wjp_rol |&gt; 
  rename(iso3c=country_code) |&gt; 
  rename_with(~ str_replace(., &quot;^x&quot;, &quot;factor_&quot;), starts_with(&quot;x&quot;))

#change wjp's year variable to YYYY format and convert to numeric 
#(adopts the first 4 digit year when in YYYY-YYYY format)
dta_wjp_rol &lt;- dta_wjp_rol |&gt; 
  mutate(year = as.numeric(str_sub(year, 1, 4)))

#cold-heartedly drop columns I'm not interested in 
dta_wgi_2025&lt;-dta_wgi_2025 |&gt; 
  select(iso3c, income_classification, year,wgi_rol)
#drop country and region name labels so these can be standardized 
dta_wjp_rol&lt;-dta_wjp_rol |&gt; 
  select(-country_year,-country,-region) |&gt; 
  rename(wjp_rol=wjp_rule_of_law_index_overall_score)


#merge dataframes
dta_rol_unified&lt;-left_join(dta_wgi_2025,
                           dta_wjp_rol,
                           by = join_by(year, iso3c), 
                           keep=FALSE) 

#add standardized and region names country names

#define country code assignments for legacy / ambigious codes
#(Note: matches devised by Claude) 
ref_iso3c_custom_names &lt;- c(ADO = &quot;Andorra&quot;,
                            ANT = &quot;Netherlands Antilles&quot;,
                            PRI = &quot;Puerto Rico&quot;,
                            REU = &quot;Réunion&quot;,
                            XKX = &quot;Kosovo&quot;)

ref_iso3c_custom_regions &lt;- c(ADO = &quot;Europe &#038; Central Asia&quot;,
                              ANT = &quot;Latin America &#038; Caribbean&quot;,
                              PRI = &quot;Latin America &#038; Caribbean&quot;,
                              REU = &quot;Sub-Saharan Africa&quot;,
                              XKX = &quot;Europe &#038; Central Asia&quot;)

#assign country names and regions:
dta_rol_unified&lt;-dta_rol_unified |&gt; 
  mutate(country_name=countrycode(iso3c, 
                                  origin='iso3c',
                                  destination = 'country.name.en',    
                                  custom_match = ref_iso3c_custom_names),
         region=countrycode(iso3c, 
                            origin='iso3c',
                            destination = 'region',    
                            custom_match =ref_iso3c_custom_regions))</pre>



<h3 class="wp-block-heading">Testing Cardinal Substitution</h3>



<p class="wp-block-paragraph">The code below basically asks whether it’s possible to estimate the <em>level </em>of WJP’s RoL index using the WGI’s RoL measure using a simple linear model. At the outset, the model’s fit is quite high at 97 percent, but we could have guessed this from the cross-country scatter we produced in our last post.</p>



<pre># Cardinal substitution: does a WGI-&gt;WJP mapping reproduce WJP levels? -----
sum_rol_country &lt;- dta_rol_unified |&gt;
  filter(!is.na(wgi_rol), !is.na(wjp_rol)) |&gt;
  summarise(wgi_rol_mean = mean(wgi_rol),
            wjp_rol_mean = mean(wjp_rol),
            .by = country_name)

mod_rol_calib &lt;- lm(wjp_rol_mean ~ wgi_rol_mean, data = sum_rol_country)

#output the R squared
summary(mod_rol_calib)$r.squared |&gt; round(2)</pre>



<p class="wp-block-paragraph">The second chunk calculates the Leave-One-Out Cross-Validation Root Mean Squared Error (LOO RMSE), which estimates prediction error for each country when it’s held out of the sample: a smaller LOO RMSE implies smaller forecast errors when predicting outside the sample. This is then scaled by the standard deviation of the country-level WJP means to make it easier to interpretat.</p>



<p class="wp-block-paragraph">The results are encouraging: the LOO RMSE indicates that using the WGI to estimate WJP levels carries a typical error of less than three percent, which is roughly 19% of the cross-country spread in WJP scores. Suggesting the WGI <em>can </em>provide a reasonable proxy when the levels are important too.</p>



<pre># Leave-One-Out Cross-Validation Root Mean Squared Error (LOO RMSE)
rlt_rol_loo_rmse   &lt;- sqrt(mean((residuals(mod_rol_calib) /
                                   (1 - hatvalues(mod_rol_calib)))^2))

#divide by standard deviation of WJP index means to put the figure in the context fo the data
rlt_rol_rmse_ratio &lt;- rlt_rol_loo_rmse / sd(sum_rol_country$wjp_rol_mean)</pre>



<h3 class="wp-block-heading">Systematic Bias</h3>



<p class="wp-block-paragraph">Of course, because the LOO RMSE measures is calculated across the entire dataset, it might hide systematic bias, such as if the forecast accuracy varies depending on the WGI score.</p>



<p class="wp-block-paragraph">This is tested in the plot below, by comparing the prediction error (residual) with the predicted value for the WJP’s index (using the WGI RoL measure). If there no systematic bias, the residuals should remain relatively stable across the predicted WJP values.</p>



<p class="wp-block-paragraph">Alas, this doesn’t appear to be the case, with the model under-predicting the WJP’s RoL index at both ends. Although this bias is relatively mild at 0.05 (in WJP index units), it does suggest the WGI is likely to be a poorer substitute for the WJP’s index for countries at either end of the RoL spectrum.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" loading="lazy" src="https://i2.wp.com/www.gilesd-j.com/wp-content/uploads/2026/07/estimate_bias.png?w=450&#038;ssl=1" alt="" class="wp-image-4256" srcset_temp="https://i2.wp.com/www.gilesd-j.com/wp-content/uploads/2026/07/estimate_bias.png?w=450&#038;ssl=1 604w, https://www.gilesd-j.com/wp-content/uploads/2026/07/estimate_bias-300x227.png 300w" sizes="auto, (max-width: 604px) 100vw, 604px" data-recalc-dims="1" /></figure>



<pre>dta_plt_rol_calib &lt;- sum_rol_country |&gt;
  mutate(wjp_pred = fitted(mod_rol_calib),
         resid    = wjp_rol_mean - wjp_pred)

plt_rol_calib &lt;- ggplot(dta_plt_rol_calib, aes(wjp_pred, resid)) +
  geom_hline(yintercept = 0, linewidth = 0.3, col = &quot;grey70&quot;) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = &quot;loess&quot;, se = FALSE, col = &quot;grey40&quot;, linewidth = 0.5) +
  labs(x = &quot;Predicted WJP (from WGI)&quot;, y = &quot;Residual (WJP units)&quot;) +
  theme_classic()

plt_rol_calib</pre>



<p class="wp-block-paragraph">However, being an applied economist means I know a simple trick: add non-linear terms to everything and see if the smile disappears.</p>



<p class="wp-block-paragraph">And it does, the smile is now a grimace: as is shown in the plot below adding a non-linear term seems to take care of the bias at either end. Notice the average errors no longer increase at either end, making the prediction relatively constant (and small) across the RoL spectrum. Suggesting the WGI <em>can </em>be trusted to predict the WJP index at either end of the spectrum provided we account for the non-linearity.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" loading="lazy" src="https://i0.wp.com/www.gilesd-j.com/wp-content/uploads/2026/07/systematic_bias_nl.png?w=450&#038;ssl=1" alt="" class="wp-image-4259" srcset_temp="https://i0.wp.com/www.gilesd-j.com/wp-content/uploads/2026/07/systematic_bias_nl.png?w=450&#038;ssl=1 604w, https://www.gilesd-j.com/wp-content/uploads/2026/07/systematic_bias_nl-300x227.png 300w" sizes="auto, (max-width: 604px) 100vw, 604px" data-recalc-dims="1" /></figure>



<pre>#reestimate the model with a non-linear WGI term 
mod_rol_calib_non_linear &lt;- lm(wjp_rol_mean ~ wgi_rol_mean + I(wgi_rol_mean^2),
                               data = sum_rol_country)


dta_plt_rol_calib_nl &lt;- sum_rol_country |&gt;
  mutate(wjp_pred = fitted(mod_rol_calib_non_linear),
         resid    = wjp_rol_mean - wjp_pred)

plt_rol_calib_nl &lt;- ggplot(dta_plt_rol_calib_nl, aes(wjp_pred, resid)) +
  geom_hline(yintercept = 0, linewidth = 0.3, col = &quot;grey70&quot;) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = &quot;loess&quot;, se = FALSE, col = &quot;grey40&quot;, linewidth = 0.5) +
  labs(x = &quot;Predicted WJP (from WGI, quadratic)&quot;, y = &quot;Residual (WJP units)&quot;) +
  theme_classic()

plt_rol_calib_nl</pre>



<h3 class="wp-block-heading">But does it drift?</h3>



<p class="wp-block-paragraph">The final question Claude suggested I ask was whether the WGI’s ability to predict the WJP’s index changes over time. The code below tests this by comparing a simple linear prediction model with one where the influence of the WGI changes over time.</p>



<p class="wp-block-paragraph">The anova() function then compares results of both models to test whether allowing the WGI’s influence to change over time improves the model’s forecasting accuracy. If it does (indicated by a significant p-value), the WGI’s ability to predict the WJP’s index might not be stable over time.</p>



<p class="wp-block-paragraph">The result: a p value of 9%, which points to the time invariant model being good enough for predicting the WJP’s index.</p>



<pre>#estimate a simple linear model with WGI's influence kept constant over time
mod_rol_calib_flat &lt;- lm(wjp_rol ~ wgi_rol, data = dta_rol_unified)

#estimate a model where WGI's influence varies over time
mod_rol_calib_yr   &lt;- lm(wjp_rol ~ wgi_rol * factor(year), data = dta_rol_unified)

#compare the prediction capacity of both models 
anova(mod_rol_calib_flat, mod_rol_calib_yr)</pre>



<h3 class="wp-block-heading">Look what Claude made me do…</h3>



<p class="wp-block-paragraph">So there you have it: the WGI can serve as a useful substitute for the WJP’s rule of law index whether you’re interested in RoL rankings <em>or </em>levels, provided you account for the non-linearity at either end of the RoL scale.</p>



<p class="wp-block-paragraph"><strong>How AI was used for this post:</strong> As this additional analysis was Claude’s suggestion <em>and </em>I was hours away from a holiday I leaned heavily on Claude for the first draft of the code. Much of the text is mine, but I did ask AI for suggestions to make sure I was explaining the analysis accurately.</p>



<p class="wp-block-paragraph"></p>
<p>The post <a href="https://www.gilesd-j.com/2026/07/21/level-with-me-can-the-wgi-predict-the-wjps-rule-of-law-scores/" rel="nofollow" target="_blank">Level With Me: Can the WGI Predict the WJP’s Rule of Law Scores?</a> appeared first on <a href="https://www.gilesd-j.com/" rel="nofollow" target="_blank">Giles</a>.</p>

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://www.gilesd-j.com/2026/07/21/level-with-me-can-the-wgi-predict-the-wjps-rule-of-law-scores/"> Data Analytics and AI Archives - Giles</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/level-with-me-can-the-wgi-predict-the-wjps-rule-of-law-scores/">Level With Me: Can the WGI Predict the WJP’s Rule of Law Scores?</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402713</post-id>	</item>
		<item>
		<title>A collection of self-starters for nonlinear regression in R</title>
		<link>https://www.r-bloggers.com/2026/07/a-collection-of-self-starters-for-nonlinear-regression-in-r-3/</link>
		
		<dc:creator><![CDATA[Andrea Onofri]]></dc:creator>
		<pubDate>Mon, 20 Jul 2026 22:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://www.statforbiology.com/posts/nls_modelFitting.html</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>Usually, the first step in every nonlinear regression analysis is to select the function  that best describes the phenomenon under study. The next step is to fit this function to the observed data, possibly by using some sort of nonlinear least ...</p></div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/a-collection-of-self-starters-for-nonlinear-regression-in-r-3/">A collection of self-starters for nonlinear regression in R</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://www.statforbiology.com/posts/nls_modelFitting.html"> Statforbiology</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
 





<p>Usually, the first step in every nonlinear regression analysis is to select the function <img src="https://latex.codecogs.com/png.latex?f"> that best describes the phenomenon under study. The next step is to fit this function to the observed data, possibly by using some sort of nonlinear least squares algorithm.</p>
<p>We have already devoted a post to the first task, which you can find <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html" rel="nofollow" target="_blank">at this link</a>.</p>
<p>As for the second step, the main problem is that nonlinear least squares algorithms are iterative, in the sense that they start from some initial guesses for the model parameters, which are continuously improved until the least squares solution is approximately reached. Quite often, providing such initial guesses for all model parameters becomes a problem: if our guesses are not close enough to the least squares estimates, the algorithm may stall and fail to converge. Or, even worse, it may converge to the wrong solution. How do we obtain good initial guesses for the model parameters? This is not easily accomplished, especially for students and practitioners. This is where self-starters come in handy.</p>
<p>Self-starter functions can automatically calculate initial values for any given dataset and, therefore, they can make nonlinear regression almost as straightforward as linear regression. From a teaching perspective, this means that the transition from linear to nonlinear models is immediate and hassle-free.</p>
<p>In another post, <a href="https://www.statforbiology.com/posts/nls_selfStarting.html" rel="nofollow" target="_blank">at this link</a>, I explained how self-starters can be built for both the <code>nls()</code> function in the ‘stats’ package and the <code>drm()</code> function in the ‘drc’ package (Ritz et al., 2019). In this post, I would like to provide an overview of the self-starting functions that already exist in R, either in the ‘stats’, ‘drc’, or ‘statforbiology’ packages. I do not aim for completeness here, as other packages also contain self-starters, such as the ‘nlraa’ package (Miguez, 2025), with which I am not sufficiently familiar. The exemplary datasets are included in the ‘statforbiology’ package and they all come from real field or greenhouse experiments; further information and citations to the original works can be found in my book (Onofri, 2026), or in the additional meterial at <a href="https://www.statforbiology.com/_statbookeng/" rel="nofollow" target="_blank">this link</a>.</p>
<section id="functions-and-curve-shapes" class="level1">
<h1>Functions and curve shapes</h1>
<p>As in the other post, I have classified linear/nonlinear regression functions according to the shape they show when they are plotted in an <em>x-y</em> graph, following the approach taken in Ratkowsky (1990):</p>
<ul>
<li>Polynomials
<ol type="1">
<li>Straight line function</li>
<li>Quadratic polynomial function</li>
</ol></li>
<li>Concave/Convex curves (no inflection)
<ol type="1">
<li>Exponential function</li>
<li>Asymptotic function / Negative exponential function</li>
<li>Power function</li>
<li>Logarithmic function</li>
<li>Rectangular hyperbola</li>
</ol></li>
<li>Sigmoidal curves
<ol type="1">
<li>Logistic function</li>
<li>Gompertz function</li>
<li>Modified Gompertz function</li>
<li>Log-logistic function</li>
<li>Weibull (type-1) function</li>
<li>Weibull (type-2) function</li>
</ol></li>
<li>Curves with maxima/minima
<ol type="1">
<li>Peaked sigmoidal function</li>
<li>Bragg function</li>
<li>Lorentz function</li>
<li>Beta function</li>
</ol></li>
</ul>
<p>To make navigation easier, you can first inspect Figure 1 to identify the type of curve of interest and then use the links above to jump directly to the corresponding section.</p>
<div class="cell">
<div class="cell-output-display">
<div id="fig-1" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://i2.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/fig-1-1.png?w=578&#038;ssl=1" class="img-fluid figure-img" style="width:95.0%" data-recalc-dims="1">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure 1: The shapes of the most important functions. The different colors indicate the possible different shapes of the same function, with different parameters. In the case of the Bragg/Lorentz function, the red color indicate the Bragg function and the blue color indicate the Lorentz function (same parameter values).
</figcaption>
</figure>
</div>
</div>
</div>
<p>First of all, we need to install (if necessary) and load these packages, by using the code below.</p>
<div class="cell">
<pre># installing package, if not yet available
# install.packages(&quot;statforbiology&quot;)

# loading package
library(statforbiology)</pre>
</div>
</section>
<section id="polynomials" class="level1">
<h1>Polynomials</h1>
<section id="straight-line-function" class="level2">
<h2 class="anchored" data-anchor-id="straight-line-function">Straight line function</h2>
<p>The equation is:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20b_0%20+%20b_1%20,%20X%20%5Cquad%20%5Cquad%20%5Cquad%20(1)"></p>
<p>Please check the details of parameter interpretation in <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html#straight-line-function" rel="nofollow" target="_blank">my previous post</a>. This is a linear model and, in R, linear regression is fitted by using the <code>lm()</code> function. However, in a few circumstances I have found it useful to fit a linear regression model by using nonlinear regression algorithms. I know that this is rather inefficient, but, as a partial excuse, I should say that some methods for ‘drc’ objects are also rather handy for linear regression, for example, to obtain parameter estimates and compare regression curves in ANCOVA models. For these unusual cases, we can use the <code>NLS.linear()</code> and <code>DRC.linear()</code> functions in the ‘statforbiology’ package.</p>
<section id="example-1" class="level3">
<h3 class="anchored" data-anchor-id="example-1">Example 1</h3>
<p>Let’s consider the ‘metamitron’ dataset, which is available in ‘statforbiology’. It describes the degradation of the sugarbeet herbicide metamitron (M) in soil, either alone or in the presence of two co-applied herbicides, namely phenmedipham (P) and chloridazon (C). Independent soil samples treated with the four herbicide combinations (i.e. M, MP, MC and MPC) were assayed at eight different times (0, 7, 14, 21, 32, 42, 55 and 67 days after treatment, with three replicates per sampling date) to determine the residual concentration of metamitron. In my book (Onofri, 2026, p. 212), I analysed this dataset by using linear regression. Here, instead, I would like to show how the same model can be fitted with the <code>drm()</code> function in the ‘drc’ package, obtaining the slopes and intercepts for all herbicide combinations directly from the output of the <code>summary()</code> method.</p>
<div class="cell">
<pre># Example of fitting four straight lines at once
library(statforbiology)
dataset &lt;- getAgroData(&quot;metamitron&quot;)
model &lt;- drm(log(Conc) ~ Time, fct = DRC.linear(),
             curveid = Herbicide, data = dataset)
summary(model)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Straight line (2 parms)

Parameter estimates:

        Estimate Std. Error t-value   p-value    
a:M    4.5159111  0.0577603  78.184 &lt; 2.2e-16 ***
a:MP   4.6304853  0.0577603  80.167 &lt; 2.2e-16 ***
a:MC   4.5401707  0.0577603  78.604 &lt; 2.2e-16 ***
a:MPC  4.7546974  0.0577603  82.318 &lt; 2.2e-16 ***
b:M   -0.0386165  0.0015585 -24.777 &lt; 2.2e-16 ***
b:MP  -0.0318908  0.0015585 -20.462 &lt; 2.2e-16 ***
b:MC  -0.0231879  0.0015585 -14.878 &lt; 2.2e-16 ***
b:MPC -0.0234014  0.0015585 -15.015 &lt; 2.2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 0.1687429 (88 degrees of freedom)</pre>
</div>
</div>
</section>
</section>
<section id="quadratic-polynomial-function" class="level2">
<h2 class="anchored" data-anchor-id="quadratic-polynomial-function">Quadratic polynomial function</h2>
<p>The equation is:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20+%20b%5C,%20X%20+%20c%20%5C,%20X%5E2%20%5Cquad%20%5Cquad%20%5Cquad%20(2)"></p>
<p>Check the post <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html#quadratic-polynomial-function" rel="nofollow" target="_blank">at this link</a> for details about the biological interpretation of the model parameters. In the same vein as the straight line function, a second-order polynomial can be fitted with the <code>lm()</code> function, but, if necessary, it can also be fitted with <code>nls()</code> or <code>drm()</code>, by using the functions <code>NLS.poly2()</code> and <code>DRC.poly2()</code>.</p>
<section id="example-2" class="level3">
<h3 class="anchored" data-anchor-id="example-2">Example 2</h3>
<p>The dataset ‘waterProductivity’ in the ‘statforbiology’ package shows the relationship between water productivity in lettuce, as affected by the irrigation regime and as determined in a simulated experiment based on the data from Toscano et al. (2026). It is expected that the relationship under study may show a maximum at an intermediate irrigation regime, which is confirmed by fitting a second-order polynomial function. This same analysis could, of course, be performed more efficiently by using linear regression.</p>
<div class="cell">
<pre>library(statforbiology)
dataset &lt;- getAgroData(&quot;waterProductivity&quot;)

# nls fit
model &lt;- nls(WP ~ NLS.poly2(Regime, a, b, c),
             data = dataset)

#drc fit
model &lt;- drm(WP ~ Regime, fct = DRC.poly2(),
             data = dataset)</pre>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Second Order Polynomial (3 parms)

Parameter estimates:

                 Estimate  Std. Error  t-value   p-value    
a:(Intercept)  1.9187e+00  2.3171e-01   8.2806 1.679e-05 ***
b:(Intercept)  4.2977e-01  8.4554e-03  50.8287 2.217e-12 ***
c:(Intercept) -3.3618e-03  6.6586e-05 -50.4884 2.355e-12 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 0.1441625 (9 degrees of freedom)</pre>
</div>
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i2.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-4-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
</div>
</section>
</section>
</section>
<section id="concaveconvex-curves" class="level1">
<h1>Concave/Convex curves</h1>
<section id="exponential-function" class="level2">
<h2 class="anchored" data-anchor-id="exponential-function">Exponential function</h2>
<p>The most common equations are:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20%20e%5E%7Bk%20%5C,%20X%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(3)"></p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20e%5E%7Bd%20+%20k%20%5C,%20X%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(4)"></p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20%20%5C,%20b%5EX%20%5Cquad%20%5Cquad%20%5Cquad%20(5)"></p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20d%20%5Cexp(-x/e)%20%5Cquad%20%5Cquad%20%5Cquad%20(6)"></p>
<p>and, for the cases where a lower asymptote <img src="https://latex.codecogs.com/png.latex?c%20%5Cneq%200"> is needed:</p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20c%20+%20(d%20-c)%20%5Cexp(-x/e)%20%5Cquad%20%5Cquad%20%5Cquad%20(7)"></p>
<p>Check the post <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html#exponential-function" rel="nofollow" target="_blank">at this link</a> for details about the model parameters. In order to fit these models, several self-starting functions are available. In the <code>statforbiology</code> package, you can find <code>NLS.expoGrowth()</code>, <code>NLS.expoDecay()</code>, <code>DRC.expoGrowth()</code>, and <code>DRC.expoDecay()</code>, which can be used to fit the exponential growth and decay models represented by Equation 3 with <code>nls()</code> and <code>drm()</code>, respectively. The <code>drc</code> package also contains the functions <code>EXD.2()</code> and <code>EXD.3()</code>, which can be used to fit Equations 6 and 7, respectively.</p>
<section id="example-3" class="level3">
<h3 class="anchored" data-anchor-id="example-3">Example 3</h3>
<p>The ‘degradation’ dataset, which is available in the ‘statforbiology’ package, refers to an herbicide degradation experiment, where the decrease in concentration over time is assumed to follow first-order kinetics, according to an exponential decay function.</p>
<div class="cell">
<pre>library(statforbiology)
data(degradation)

# nls fit
model &lt;- nls(Conc ~ NLS.expoDecay(Time, a, k),
             data = degradation)

# drm fit
model &lt;- drm(Conc ~ Time, fct = DRC.expoDecay(),
             data = degradation)
summary(model)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Exponential Decay Model (2 parms)

Parameter estimates:

                 Estimate Std. Error t-value   p-value    
C0:(Intercept) 99.6349312  1.4646680  68.026 &lt; 2.2e-16 ***
k:(Intercept)   0.0670391  0.0019089  35.120 &lt; 2.2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 2.621386 (22 degrees of freedom)</pre>
</div>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i2.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-6-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
</div>
</section>
</section>
<section id="asymptotic-function" class="level2">
<h2 class="anchored" data-anchor-id="asymptotic-function">Asymptotic function</h2>
<p>The following parameterisations are available:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20-%20(a%20-%20b)%20%5C,%20%5Cexp%20(-%20m%20%5C,%20X)%20%5Cquad%20%5Cquad%20%5Cquad%20(8)"></p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20(d%20-%20c)%20%5C,%20%5Cleft%5B1%20-%20%5Cexp%20%5Cleft(-%20%5Cfrac%7BX%7D%7Be%7D%20%5Cright)%20%5Cright%5D%20%5Cquad%20%5Cquad%20%5Cquad%20(9)"></p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20-%20(a%20-%20b)%20%5C,%20%5Cexp%20(-%20log(f)%5C,%20X)%20%5Cquad%20%5Cquad%20%5Cquad%20(10)"></p>
<p>If we set <img src="https://latex.codecogs.com/png.latex?b%20=%200"> (or, equivalently, <img src="https://latex.codecogs.com/png.latex?c%20=%200">) in the equations above, we obtain a curve passing through the origin, which is usually referred to as the <em>negative exponential function</em> and is most commonly parameterised as:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20%5Cleft%5B%201-%20%5Cexp%20(-%20m%20X)%20%5Cright%5D%20%5Cquad%20%5Cquad%20%5Cquad%20(11)"></p>
<p>Check the post <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html#asymptotic-function" rel="nofollow" target="_blank">at this link</a> for details about the model parameters. To fit the asymptotic function, the ‘statforbiology’ package contains the self-starting routines <code>NLS.asymReg()</code> and <code>DRC.asymReg()</code>, which can be used to fit Eq. 8 with <code>nls()</code> and <code>drm()</code>, respectively. The ‘drc’ package contains the function <code>AR.3()</code> to fit Eq. 9 with <code>drm()</code>, while the ‘stats’ package contains <code>SSasymp()</code>, which can be used to fit Eq. 10 with <code>nls()</code>. The negative exponential function can be fitted with <code>NLS.negExp()</code>, <code>DRC.negExp()</code> (in ‘statforbiology’), <code>AR.2()</code> (in ‘drc’), and <code>SSasympOrig()</code> (in ‘stats’).</p>
<section id="example-4" class="level3">
<h3 class="anchored" data-anchor-id="example-4">Example 4</h3>
<p>In this example, we consider a growth curve where the weight of a crop is measured at different times. As the data do not show any visible inflection point, we fit an asymptotic regression model.</p>
<div class="cell">
<pre>Time &lt;- c(1, 3, 5, 7, 9, 11, 13, 20)
Weight &lt;- c(8.22, 14.0, 17.2, 16.9, 19.2, 19.6, 19.4, 19.6)

# nls fit
model &lt;- nls(Weight ~ NLS.asymReg(Time, b, m, a) )

# drm fit
model &lt;- drm(Weight ~ Time, fct = DRC.asymReg(names = c(&quot;b&quot;, &quot;m&quot;, &quot;a&quot;)))
summary(model)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Asymptotic Regression Model (3 parms)

Parameter estimates:

               Estimate Std. Error t-value   p-value    
b:(Intercept)  3.756123   1.367835  2.7460  0.040500 *  
m:(Intercept)  0.337078   0.052704  6.3957  0.001385 ** 
a:(Intercept) 19.629817   0.420557 46.6758 8.525e-08 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 0.639656 (5 degrees of freedom)</pre>
</div>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i1.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-8-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
</div>
</section>
</section>
<section id="power-function" class="level2">
<h2 class="anchored" data-anchor-id="power-function">Power function</h2>
<p>The most common parameterisation is:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20%5C,%20X%5Eb%20%5Cquad%20%5Cquad%20%5Cquad%20(12)"></p>
<p>Check the post <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html#power-function" rel="nofollow" target="_blank">at this link</a> for details about the model parameters. This function can be fitted by using the self-starting functions <code>DRC.powerCurve()</code> and <code>NLS.powerCurve()</code> in the ‘statforbiology’ package.</p>
<section id="example-5" class="level3">
<h3 class="anchored" data-anchor-id="example-5">Example 5</h3>
<p>The ‘speciesArea’ dataset in the ‘statforbiology’ package was obtained from an experiment aimed at determining the species–area relationship for the weed community in an orange grove. The response variable is the number of species, while the predictor is the sampled area.</p>
<div class="cell">
<pre>library(statforbiology)
speciesArea &lt;- getAgroData(&quot;speciesArea&quot;)

#nls fit
model &lt;- nls(numSpecies ~ NLS.powerCurve(Area, a, b),
             data = speciesArea)

# drm fit
model &lt;- drm(numSpecies ~ Area, fct = DRC.powerCurve(),
             data = speciesArea)
summary(model)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Power curve (Freundlich equation) (2 parms)

Parameter estimates:

              Estimate Std. Error t-value   p-value    
a:(Intercept) 4.348404   0.337197  12.896 3.917e-06 ***
b:(Intercept) 0.329770   0.016723  19.719 2.155e-07 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 0.9588598 (7 degrees of freedom)</pre>
</div>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i2.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-10-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
</div>
</section>
</section>
<section id="logarithmic-function" class="level2">
<h2 class="anchored" data-anchor-id="logarithmic-function">Logarithmic function</h2>
<p>It has the following main parameterisation:</p>
<p><img src="https://latex.codecogs.com/png.latex?y%20=%20a%20+%20b%20%5C,%20%5Clog(X)%20%5Cquad%20%5Cquad%20%5Cquad%20(13)"></p>
<p>Check the post <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html#logarithmic-function" rel="nofollow" target="_blank">at this link</a> for details about the parameters. The logarithmic function can be fitted by using <code>lm()</code>, with a log-transformed predictor. If necessary, it can also be fitted by using <code>nls()</code> and <code>drm()</code>, with the self-starting functions <code>NLS.logCurve()</code> and <code>DRC.logCurve()</code>, which are available in the ‘statforbiology’ package.</p>
<section id="example-6" class="level3">
<h3 class="anchored" data-anchor-id="example-6">Example 6</h3>
<p>In this example, we use the ‘speciesArea’ dataset to fit a logarithmic curve, which is another candidate model for describing species–area curves. In this case, based on the AIC value, we can conclude that the power function provides a better fit to the observed data.</p>
<div class="cell">
<pre>library(statforbiology)
speciesArea &lt;- getAgroData(&quot;speciesArea&quot;)

#nls fit
model2 &lt;- nls(numSpecies ~ NLS.logCurve(Area, a, b),
             data = speciesArea)

# drm fit
model2 &lt;- drm(numSpecies ~ Area, fct = DRC.logCurve(),
             data = speciesArea)
summary(model2)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Linear regression on log-transformed x (2 parms)

Parameter estimates:

              Estimate Std. Error t-value   p-value    
a:(Intercept)  1.51111    1.17401  1.2871     0.239    
b:(Intercept)  4.06359    0.35575 11.4224 8.847e-06 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 1.910082 (7 degrees of freedom)</pre>
</div>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i0.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-12-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-stdout">
<pre>       df      AIC
model   3 28.52288
model2  3 40.92769</pre>
</div>
</div>
</section>
</section>
<section id="rectangular-hyperbola" class="level2">
<h2 class="anchored" data-anchor-id="rectangular-hyperbola">Rectangular hyperbola</h2>
<p>Common parameterisations are:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20%5Cfrac%7Ba%20%5C,%20X%7D%20%7Bb%20+%20X%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(14)"></p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20%5Cfrac%7Bd%7D%7B1%20+%20%5Cfrac%7Be%7D%7BX%7D%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(15)"></p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20%5Cfrac%7Bd%20-%20c%7D%7B1%20+%20%5Cfrac%7Be%7D%7BX%7D%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(15a)"></p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20%5Cfrac%7Bi%20%5C,%20X%7D%7B1%20+%20%5Cfrac%7Bi%20%5C,%20X%20%7D%7Ba%7D%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(16)"></p>
<p>The derivation of the alternative parameterisations and the interpretation of the parameters are described in another post <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html#rectangular-hyperbola" rel="nofollow" target="_blank">at this link</a>. In R, the rectangular hyperbola can be fitted by using ‘nls()’ and the self-starting function <code>SSmicmen()</code>, available in the ‘nlme’ package. If you prefer a ‘drm()’ fit, you can use the <code>MM.2()</code> and <code>MM.3()</code> functions in the ‘drc’ package, which use the parameterisations in Eq. 15 and 15a, respectively. For competition studies, Eq. 16 is available through the self-starting functions <code>NLS.YL()</code> and <code>DRC.YL()</code>.</p>
<section id="example-7" class="level3">
<h3 class="anchored" data-anchor-id="example-7">Example 7</h3>
<p>The dataset ‘Ammi94_YL’ contains the results of a competition experiment on the effect of increasing densities of the weed species <em>Ammi majus</em> on sunflower achene yield. Yield data were expressed as yield losses relative to the yield in weed-free plots and were used as the response variable to fit Eq. 16 and derive the competition index <img src="https://latex.codecogs.com/png.latex?i">.</p>
<div class="cell">
<pre>library(statforbiology)
dataset &lt;- getAgroData(&quot;Ammi94_YL&quot;)

#drm fit
model &lt;- drm(YL ~ Density, fct = DRC.YL(), data = dataset)
summary(model)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Yield-Loss function (Cousens, 1985) (2 parms)

Parameter estimates:

               Estimate Std. Error t-value p-value  
i:(Intercept) 0.0118359  0.0045637  2.5935 0.02228 *
A:(Intercept) 0.4841796  0.1863969  2.5976 0.02211 *
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 0.05453432 (13 degrees of freedom)</pre>
</div>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i0.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-14-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
</div>
</section>
</section>
</section>
<section id="sigmoidal-function" class="level1">
<h1>Sigmoidal curves</h1>
<p>In the previous post (<a href="https://www.statforbiology.com/posts/nls_usefulEquations.qmd" rel="nofollow" target="_blank">at this link</a>) we examined six different sigmoidal shapes based on <img src="https://latex.codecogs.com/png.latex?X">, to be selected according to the expected symmetry of the response. The equations are the logistic, Gompertz, and modified Gompertz functions, with the following three equations, respectively:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20%5Cfrac%7Bd%20-%20c%7D%7B1%20+%20exp(-%20b%20(X%20-%20e))%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(17)"></p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20c%20+%20(d%20-%20c)%20%5Cexp%20%5Cleft%5C%7B-%20%5Cexp%20%5Cleft%5B%20-%20b%20%5C,%20(X%20-%20e)%20%5Cright%5D%20%5Cright%5C%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(18)"></p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20c%20+%20(d%20-%20c)%20%5Cleft%5C%7B%201%20-%20%5Cexp%20%5Cleft%5C%7B-%20%5Cexp%20%5Cleft%5B%20b%20%5C,%20(X%20-%20e)%20%5Cright%5D%20%5Cright%5C%7D%20%5Cright%5C%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(19)"></p>
<p>The same curves can be based on the logarithm of <img src="https://latex.codecogs.com/png.latex?X">, to obtain the corresponding log-logistic, Type-1 Weibull, and Type-2 Weibull equations, which are, respectively:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20%5Cfrac%7Bd%20-%20c%7D%7B1%20+%20%5Cexp%20%5Cleft%5C%7B%20-%20b%20%5Cleft%5B%20%5Clog(X)%20-%20%5Clog(e)%20%5Cright%5D%20%5Cright%5C%7D%20%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(20)"></p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20c%20+%20(d%20-%20c)%20%5Cexp%20%5Cleft%5C%7B-%20%5Cexp%20%5Cleft%5B%20-%20b%20%5C,%20(%5Clog(X)%20-%20%5Clog(e))%20%5Cright%5D%20%5Cright%5C%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(21)"></p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20c%20+%20(d%20-%20c)%20%5Cleft%5C%7B%201%20-%20%5Cexp%20%5Cleft%5C%7B-%20%5Cexp%20%5Cleft%5B%20b%20%5C,%20(%5Clog(X)%20-%20%5Clog(e))%20%5Cright%5D%20%5Cright%5C%7D%20%5Cright%5C%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(22)"></p>
<p>The meaning of the model parameters and details about the shapes can be found in another post <a href="https://www.statforbiology.com/posts/nls_UsefulEquations.qmd#sigmoidal" rel="nofollow" target="_blank">at this link</a>.</p>
<p>For all these four-parameter curves, it is possible to set <img src="https://latex.codecogs.com/png.latex?c%20=%200"> to obtain the three-parameter curves (17a), (18a), (19a), (20a), (21a), and (22a). Likewise, we can constrain both <img src="https://latex.codecogs.com/png.latex?c%20=%200"> and <img src="https://latex.codecogs.com/png.latex?d%20=%201"> to obtain the two-parameter curves (17b), (18b), (19b), (20b), (21b), and (22b). The collection of self-starters is huge; therefore, I will provide a summary table.</p>
<table class="caption-top table">
<caption>List of sigmoidal functions, together with self-starters for fitting with <code>drm()</code> and <code>nls()</code>. (1) These self-starters are included in the ‘drc’ package and the corresponding curves have an increasing shape when <img src="https://latex.codecogs.com/png.latex?b%20%3C%200"> and a decreasing shape when <img src="https://latex.codecogs.com/png.latex?b%20%3E%200">. For all other self-starters, which are available in the ‘statforbiology’ package, the reverse is true (which is the most common definition, apart from the case of herbicide bioassays){#tbl-models}</caption>
<colgroup>
<col style="width: 45%">
<col style="width: 13%">
<col style="width: 20%">
<col style="width: 20%">
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Name</th>
<th style="text-align: left;">Eq. No.</th>
<th style="text-align: left;">for <code>drm()</code></th>
<th style="text-align: left;">for <code>nls()</code></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Logistic (4-parameters)</td>
<td style="text-align: left;">(17)</td>
<td style="text-align: left;"><code>L.4()</code> (1)</td>
<td style="text-align: left;"><code>NLS.L4()</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Logistic (3-parameters)</td>
<td style="text-align: left;">(17a)</td>
<td style="text-align: left;"><code>L.3()</code> (1)</td>
<td style="text-align: left;"><code>NLS.L3()</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Logistic (2-parameters)</td>
<td style="text-align: left;">(17b)</td>
<td style="text-align: left;"><code>L.2()</code> (1)</td>
<td style="text-align: left;"><code>NLS.L2()</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Gompertz (4-parameters)</td>
<td style="text-align: left;">(18)</td>
<td style="text-align: left;"><code>G.4()</code> (1)</td>
<td style="text-align: left;"><code>NLS.G4()</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Gompertz (3-parameters)</td>
<td style="text-align: left;">(18a)</td>
<td style="text-align: left;"><code>G.3()</code> (1)</td>
<td style="text-align: left;"><code>NLS.G3()</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Gompertz (2-parameters)</td>
<td style="text-align: left;">(18b)</td>
<td style="text-align: left;"><code>G.2()</code> (1)</td>
<td style="text-align: left;"><code>NLS.G2()</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">mod-Gompertz (4-parameters)</td>
<td style="text-align: left;">(19)</td>
<td style="text-align: left;"><code>DRC.E4()</code></td>
<td style="text-align: left;"><code>NLS.E4()</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">mod-Gompertz (3-parameters)</td>
<td style="text-align: left;">(19a)</td>
<td style="text-align: left;"><code>DRC.E3()</code></td>
<td style="text-align: left;"><code>NLS.E3()</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">mod-Gompertz (2-parameters)</td>
<td style="text-align: left;">(19b)</td>
<td style="text-align: left;"><code>DRC.E2()</code></td>
<td style="text-align: left;"><code>NLS.E2()</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Log-logistic (4-parameters)</td>
<td style="text-align: left;">(20)</td>
<td style="text-align: left;"><code>LL.4()</code> (1)</td>
<td style="text-align: left;"><code>NLS.LL4()</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Log-logistic (3-parameters)</td>
<td style="text-align: left;">(20a)</td>
<td style="text-align: left;"><code>LL.3()</code> (1)</td>
<td style="text-align: left;"><code>NLS.LL3()</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Log-logistic (2-parameters)</td>
<td style="text-align: left;">(20b)</td>
<td style="text-align: left;"><code>LL.2()</code> (1)</td>
<td style="text-align: left;"><code>NLS.LL2()</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Type-1 Weibull (4-parameters)</td>
<td style="text-align: left;">(21)</td>
<td style="text-align: left;"><code>W1.4()</code> (1)</td>
<td style="text-align: left;"><code>NLS.W1.4()</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Type-1 Weibull (3-parameters)</td>
<td style="text-align: left;">(21a)</td>
<td style="text-align: left;"><code>W1.3()</code> (1)</td>
<td style="text-align: left;"><code>NLS.W1.3()</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Type-1 Weibull (2-parameters)</td>
<td style="text-align: left;">(21b)</td>
<td style="text-align: left;"><code>W1.2()</code> (1)</td>
<td style="text-align: left;"><code>NLS.W1.2()</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Type-2 Weibull (4-parameters)</td>
<td style="text-align: left;">(22)</td>
<td style="text-align: left;"><code>W2.4()</code> (1)</td>
<td style="text-align: left;"><code>NLS.W2.4()</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Type-2 Weibull (3-parameters)</td>
<td style="text-align: left;">(22a)</td>
<td style="text-align: left;"><code>W2.3()</code> (1)</td>
<td style="text-align: left;"><code>NLS.W2.3()</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Type-2 Weibull (2-parameters)</td>
<td style="text-align: left;">(22b)</td>
<td style="text-align: left;"><code>W2.2()</code> (1)</td>
<td style="text-align: left;"><code>NLS.W2.2()</code></td>
</tr>
</tbody>
</table>
<section id="example-8" class="level2">
<h2 class="anchored" data-anchor-id="example-8">Example 8</h2>
<p>The dataset ‘beetGrowth’ in the ‘statforbiology’ package reports the results of an experiment in which the growth of sugar beet was evaluated under either weed-free or weed-infested conditions. In the following example, we consider the time course of crop weight under infested conditions and fit the logistic, Gompertz, and modified Gompertz functions to the observed data. We see that, based on the AIC, the three fits are equivalent in practice. We fit the same models with ‘drm()’ to show that the two fitting functions give the same results, apart from the sign of the <img src="https://latex.codecogs.com/png.latex?b"> parameter, which is reversed in the <code>L.3()</code> function.</p>
<div class="cell">
<pre>library(statforbiology)
beetGrowth &lt;- getAgroData(&quot;beetGrowth&quot;)

# nls fit
model.1 &lt;- nls(Infested ~ NLS.L3(DAE, b, d, e), data = beetGrowth)
model.2 &lt;- nls(Infested ~ NLS.G3(DAE, b, d, e), data = beetGrowth)
model.3 &lt;- nls(Infested ~ NLS.E3(DAE, b, d, e), data = beetGrowth)
AIC(model.1, model.2, model.3)</pre>
<div class="cell-output cell-output-stdout">
<pre>        df      AIC
model.1  4 250.2906
model.2  4 250.7596
model.3  4 250.8456</pre>
</div>
<pre>summary(model.1)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Formula: Infested ~ NLS.L3(DAE, b, d, e)

Parameters:
   Estimate Std. Error t value Pr(&gt;|t|)    
b 1.188e-01  1.874e-02   6.338 1.33e-05 ***
d 2.512e+03  1.277e+02  19.671 4.01e-12 ***
e 5.803e+01  1.823e+00  31.836 3.46e-15 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 222 on 15 degrees of freedom

Number of iterations to convergence: 6 
Achieved convergence tolerance: 4.299e-06</pre>
</div>
<pre># drm fit
model &lt;- drm(Infested ~ DAE, fct = L.3(), data = beetGrowth)
summary(model)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Logistic (ED50 as parameter) with lower limit fixed at 0 (3 parms)

Parameter estimates:

                Estimate Std. Error t-value   p-value    
b:(Intercept)   -0.11876    0.01832  -6.483 1.033e-05 ***
d:(Intercept) 2511.95664  127.95600  19.631 4.131e-12 ***
e:(Intercept)   58.03099    1.83458  31.632 3.788e-15 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 221.9644 (15 degrees of freedom)</pre>
</div>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i0.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-16-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
</div>
</section>
<section id="example-9" class="level2">
<h2 class="anchored" data-anchor-id="example-9">Example 9</h2>
<p>The dataset ‘brassica’ in the ‘statforbiology’ package reports the results of a short-term pot bioassay to determine the phytotoxicity of imazethapyr in hydroponic solution (Onofri, 1994). The response variable is the weight of the test plant (<em>Brassica rapa</em>), as affected by the herbicide concentration in the nutrient solution, which requires a decreasing sigmoidal curve. In the code below, we fit both a 4-parameter log-logistic and a 3-parameter log-logistic (with <img src="https://latex.codecogs.com/png.latex?c%20=%200">) function and graphically compare the two fits.</p>
<div class="cell">
<pre>library(statforbiology)
brassica &lt;- getAgroData(&quot;brassica&quot;)
model.1 &lt;- drm(FW ~ Dose, fct = LL.4(), data = brassica)
model.2 &lt;- drm(FW ~ Dose, fct = LL.3(), data = brassica)</pre>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i2.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-18-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
</div>
</section>
</section>
<section id="curve-maxima" class="level1">
<h1>Curves with maxima/minima</h1>
<p>Curves with maxima are most often used to model phenomena where the response variable reaches a maximum value at a certain level of the <img src="https://latex.codecogs.com/png.latex?X"> variable and decreases afterwards. In a previous post, we showed four possible functions, namely the sigmoidal peaked function, the Bragg function, the Lorentz function, and the beta function, with the following equations, respectively. The numbering refers to the post <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html#maxima-fun" rel="nofollow" target="_blank">at this link</a>, where you can find further information on model parameters and their biological meaning.</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20%5Cfrac%7Bd%20-%20c%20+%20f%20%5C,%20X%7D%7B1%20+%20%5Cexp%20%5Cleft%5C%7B%20-%20b%20%5Cleft%5B%20%5Clog(X)%20-%20%5Clog(e)%20%5Cright%5D%20%5Cright%5C%7D%20%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(23)"></p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20(d%20-%20c)%20%5C,%20%5Cexp%20%5Cleft%5B%20-%20b%20(X%20-%20e)%5E2%20%5Cright%5D%20%5Cquad%20%5Cquad%20%5Cquad%20(24a)"></p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20%5Cfrac%7Bd%20-%20c%7D%20%7B%201%20+%20b%20(X%20-%20e)%5E2%20%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(25a)"></p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20d%20%5C,%5Cleft%5C%7B%20%20%5Cleft(%20%5Cfrac%7BX%20-%20X_b%7D%7BX_o%20-%20X_b%7D%20%5Cright)%20%5Cleft(%20%5Cfrac%7BX_c%20-%20X%7D%7BX_c%20-%20X_o%7D%20%5Cright)%20%5E%20%7B%5Cfrac%7BX_c%20-%20X_o%7D%7BX_o%20-%20X_b%7D%7D%20%5Cright%5C%7D%5Eb%20%5Cquad%20%5Cquad%20%5Cquad%20(26)"></p>
<p>The sigmoidal peaked function (Eq. 23) can be fitted with <code>drm()</code>, by using the self-starter ‘BC.5()’. Another self-starter is available to impose the constraint <img src="https://latex.codecogs.com/png.latex?c%20=%200"> in Eq. 23, namely <code>BC.4()</code>. For the Bragg function, self-starters are available in ‘statforbiology’, which can be used to fit Eq. 24a with both <code>nls()</code> and <code>drm()</code>, namely <code>NLS.Bragg.4()</code> and <code>DRC.Bragg.4()</code>. <code>NLS.Bragg.3()</code> and <code>DRC.Bragg.3()</code> allow us to constrain <img src="https://latex.codecogs.com/png.latex?c%20=%200">. Finally, for the Lorentz equation, the self-starters are <code>NLS.Lorentz.4()</code> and <code>DRC.Lorentz.4()</code>, as well as, for the constrained version, <code>NLS.Lorentz.3()</code> and <code>DRC.Lorentz.3()</code>.</p>
<p>Curves with maxima have been used in bioassay studies to describe the stimulation of growth at low doses and in seed germination studies to describe the effect of temperature on the germination rates of seed lots.</p>
<section id="example-10" class="level2">
<h2 class="anchored" data-anchor-id="example-10">Example 10</h2>
<p>The dataset ‘SOLNI-hormesis’ in the ‘statforbiology’ package reports the results of a pot bioassay study evaluating the efficacy of rimsulfuron against <em>Solanum nigrum</em> at the 4-leaf stage. The response curve shows clear signs of stimulation at low herbicide doses (hormesis), which needs to be described by using a peaked sigmoidal function.</p>
<div class="cell">
<pre>library(statforbiology)
dataset &lt;- getAgroData(&quot;SOLNI_hormesis&quot;)
model &lt;- drm(FW ~ Dose, fct = BC.5(),
            data = dataset)
summary(model)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Brain-Cousens (hormesis) (5 parms)

Parameter estimates:

              Estimate Std. Error t-value   p-value    
b:(Intercept)  3.57034    1.25309  2.8492 0.0082868 ** 
c:(Intercept)  3.76335    0.85964  4.3778 0.0001619 ***
d:(Intercept) 14.14991    1.36933 10.3334 6.992e-11 ***
e:(Intercept)  2.85405    0.76931  3.7099 0.0009485 ***
f:(Intercept)  5.26894    3.38238  1.5578 0.1309350    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 2.97547 (27 degrees of freedom)</pre>
</div>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i2.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-20-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
</div>
</section>
<section id="example-11" class="level2">
<h2 class="anchored" data-anchor-id="example-11">Example 11</h2>
<p>The dataset ‘Hordeum_GR’ reports the germination rates of <em>Hordeum spontaneum</em> as affected by environmental temperatures. We clearly see that the response reaches a maximum value at intermediate temperature levels.</p>
<div class="cell">
<pre>library(statforbiology)
dataset &lt;- getAgroData(&quot;Hordeum_GR&quot;)
model &lt;- drm(GR50 ~ Temp, fct = DRC.bragg.4(),
            data = dataset)
summary(model)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Bragg equation with four parameters

Parameter estimates:

                Estimate Std. Error t-value   p-value    
b:(Intercept)  0.0052849  0.0036063  1.4654 0.2804269    
c:(Intercept)  0.0039006  0.0131491  0.2966 0.7947090    
d:(Intercept)  0.0290870  0.0010552 27.5646 0.0013135 ** 
e:(Intercept) 18.0013282  0.5220972 34.4789 0.0008401 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 0.001544712 (2 degrees of freedom)</pre>
</div>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i1.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-22-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
</div>
</section>
</section>
<section id="conclusions" class="level1">
<h1>Conclusions</h1>
<p>Here we are; I hope that this deep dive into nonlinear regression was useful. Thanks for reading! And … don’t forget to check out my new book!</p>
<p>Prof. Andrea Onofri<br>
Department of Agricultural, Food and Environmental Sciences<br>
University of Perugia (Italy)<br>
Send comments to: <a href="mailto:andrea.onofri@unipg.it" rel="nofollow" target="_blank">andrea.onofri@unipg.it</a></p>
<p><a href="https://www.awin1.com/cread.php?awinmid=26429&#038;awinaffid=2675822&#038;ued=https%3A%2F%2Flink.springer.com%2Fbook%2F10.1007%2F978-3-032-08199-5" rel="nofollow" target="_blank"><img src="https://i0.wp.com/www.statforbiology.com/Figures/Email_Signature_978-3-032-08199-5.png?w=578&#038;ssl=1" alt="Book cover" class="cover" align="center" data-recalc-dims="1"></a></p>
<hr>
</section>
<section id="further-readings" class="level1">
<h1>Further readings</h1>
<ol type="1">
<li>Miguez, F., Archontoulis, S., Dokoohaki, H., Glaz, B., Yeater, K.M., 2018. Chapter 15: Nonlinear Regression Models and Applications, in: ACSESS Publications. American Society of Agronomy, Crop Science Society of America, and Soil Science Society of America, Inc.</li>
<li>Onofri, A., 2026. Field Research Methods in Agriculture: An Introduction with R. Springer Nature Switzerland, Cham. https://doi.org/10.1007/978-3-032-08199-5</li>
<li>Ratkowsky, D.A., 1990. Handbook of nonlinear regression models. Marcel Dekker Inc., New York, USA.</li>
<li>Ritz, C., Jensen, S. M., Gerhard, D., Streibig, J. C. (2019) Dose-Response Analysis Using R. CRC Press Miguez F (2025). <em>nlraa: Nonlinear Regression for Agricultural Applications</em>. doi:10.32614/CRAN.package.nlraa <a href="https://doi.org/10.32614/CRAN.package.nlraa" class="uri" rel="nofollow" target="_blank">https://doi.org/10.32614/CRAN.package.nlraa</a>, R package version 1.9.10, <a href="https://cran.r-project.org/package=nlraa" class="uri" rel="nofollow" target="_blank">https://CRAN.R-project.org/package=nlraa</a>.</li>
</ol>
<p>This post was originally published in this blog on 2020-02-26.</p>


</section>

 
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://www.statforbiology.com/posts/nls_modelFitting.html"> Statforbiology</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/a-collection-of-self-starters-for-nonlinear-regression-in-r-3/">A collection of self-starters for nonlinear regression in R</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402845</post-id>	</item>
	</channel>
</rss>
